1*f3c23159Sop /* $OpenBSD: execute.c,v 1.16 2022/08/08 17:57:05 op Exp $ */
2df930be7Sderaadt /* $NetBSD: execute.c,v 1.3 1995/03/23 08:34:38 cgd Exp $ */
3df930be7Sderaadt
4df930be7Sderaadt /*
5df930be7Sderaadt * Copyright (c) 1980, 1993
6df930be7Sderaadt * The Regents of the University of California. All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
9df930be7Sderaadt * modification, are permitted provided that the following conditions
10df930be7Sderaadt * are met:
11df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
12df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
13df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
14df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
15df930be7Sderaadt * documentation and/or other materials provided with the distribution.
167a09557bSmillert * 3. Neither the name of the University nor the names of its contributors
17df930be7Sderaadt * may be used to endorse or promote products derived from this software
18df930be7Sderaadt * without specific prior written permission.
19df930be7Sderaadt *
20df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30df930be7Sderaadt * SUCH DAMAGE.
31df930be7Sderaadt */
32df930be7Sderaadt
33df930be7Sderaadt #include <sys/stat.h>
3491d73282Smestre
35bb3b10f2Spjanzen #include <err.h>
3691d73282Smestre #include <stdio.h>
37bb3b10f2Spjanzen #include <stdlib.h>
3891d73282Smestre #include <string.h>
39ee7acb09Stb #include <time.h>
4091d73282Smestre
4191d73282Smestre #include "monop.ext"
42df930be7Sderaadt
43df930be7Sderaadt typedef struct stat STAT;
44df930be7Sderaadt typedef struct tm TIME;
45df930be7Sderaadt
46bb3b10f2Spjanzen static char buf[257];
47df930be7Sderaadt
48df930be7Sderaadt static bool new_play; /* set if move on to new player */
49df930be7Sderaadt
50c72b5b24Smillert static void show_move(void);
51bb3b10f2Spjanzen
52bb3b10f2Spjanzen /*
53bb3b10f2Spjanzen * This routine takes user input and puts it in buf
54bb3b10f2Spjanzen */
55bb3b10f2Spjanzen void
getbuf(void)56211c4183Smestre getbuf(void)
57bb3b10f2Spjanzen {
58bb3b10f2Spjanzen char *sp;
59bb3b10f2Spjanzen int tmpin, i;
60bb3b10f2Spjanzen
61bba3186fSpjanzen i = 1;
62bb3b10f2Spjanzen sp = buf;
63bba3186fSpjanzen while (((tmpin = getchar()) != '\n') && (i < (int)sizeof(buf)) &&
64bb3b10f2Spjanzen (tmpin != EOF)) {
65bb3b10f2Spjanzen *sp++ = tmpin;
66bb3b10f2Spjanzen i++;
67bb3b10f2Spjanzen }
68bb3b10f2Spjanzen if (tmpin == EOF) {
69bb3b10f2Spjanzen printf("user closed input stream, quitting...\n");
70bb3b10f2Spjanzen exit(0);
71bb3b10f2Spjanzen }
72bb3b10f2Spjanzen *sp = '\0';
73bb3b10f2Spjanzen }
74df930be7Sderaadt /*
75df930be7Sderaadt * This routine executes the given command by index number
76df930be7Sderaadt */
77bb3b10f2Spjanzen void
execute(int com_num)78211c4183Smestre execute(int com_num)
79bb3b10f2Spjanzen {
80df930be7Sderaadt new_play = FALSE; /* new_play is true if fixing */
81df930be7Sderaadt (*func[com_num])();
82df930be7Sderaadt notify();
83df930be7Sderaadt force_morg();
84df930be7Sderaadt if (new_play)
85df930be7Sderaadt next_play();
86df930be7Sderaadt else if (num_doub)
87df930be7Sderaadt printf("%s rolled doubles. Goes again\n", cur_p->name);
88df930be7Sderaadt }
89df930be7Sderaadt /*
90df930be7Sderaadt * This routine moves a piece around.
91df930be7Sderaadt */
92bb3b10f2Spjanzen void
do_move(void)93211c4183Smestre do_move(void)
94bb3b10f2Spjanzen {
95bb3b10f2Spjanzen int r1, r2;
96bb3b10f2Spjanzen bool was_jail;
97df930be7Sderaadt
98df930be7Sderaadt new_play = was_jail = FALSE;
99df930be7Sderaadt printf("roll is %d, %d\n", r1 = roll(1, 6), r2 = roll(1, 6));
100df930be7Sderaadt if (cur_p->loc == JAIL) {
101df930be7Sderaadt was_jail++;
102df930be7Sderaadt if (!move_jail(r1, r2)) {
103df930be7Sderaadt new_play++;
104df930be7Sderaadt goto ret;
105df930be7Sderaadt }
106df930be7Sderaadt }
107df930be7Sderaadt else {
108df930be7Sderaadt if (r1 == r2 && ++num_doub == 3) {
109df930be7Sderaadt printf("That's 3 doubles. You go to jail\n");
110df930be7Sderaadt goto_jail();
111df930be7Sderaadt new_play++;
112df930be7Sderaadt goto ret;
113df930be7Sderaadt }
114df930be7Sderaadt move(r1 + r2);
115df930be7Sderaadt }
116df930be7Sderaadt if (r1 != r2 || was_jail)
117df930be7Sderaadt new_play++;
118df930be7Sderaadt ret:
119df930be7Sderaadt return;
120df930be7Sderaadt }
121df930be7Sderaadt /*
122df930be7Sderaadt * This routine moves a normal move
123df930be7Sderaadt */
124bb3b10f2Spjanzen void
move(int rl)125211c4183Smestre move(int rl)
126bb3b10f2Spjanzen {
127bb3b10f2Spjanzen int old_loc;
128df930be7Sderaadt
129df930be7Sderaadt old_loc = cur_p->loc;
130df930be7Sderaadt cur_p->loc = (cur_p->loc + rl) % N_SQRS;
131df930be7Sderaadt if (cur_p->loc < old_loc && rl > 0) {
132df930be7Sderaadt cur_p->money += 200;
133df930be7Sderaadt printf("You pass %s and get $200\n", board[0].name);
134df930be7Sderaadt }
135df930be7Sderaadt show_move();
136df930be7Sderaadt }
137df930be7Sderaadt /*
138df930be7Sderaadt * This routine shows the results of a move
139df930be7Sderaadt */
140bb3b10f2Spjanzen static void
show_move(void)141211c4183Smestre show_move(void)
142bb3b10f2Spjanzen {
143bb3b10f2Spjanzen SQUARE *sqp;
144df930be7Sderaadt
145bba3186fSpjanzen sqp = &board[(int)cur_p->loc];
146df930be7Sderaadt printf("That puts you on %s\n", sqp->name);
147df930be7Sderaadt switch (sqp->type) {
148df930be7Sderaadt case SAFE:
149df930be7Sderaadt printf("That is a safe place\n");
150df930be7Sderaadt break;
151df930be7Sderaadt case CC:
152bb3b10f2Spjanzen cc();
153bb3b10f2Spjanzen break;
154df930be7Sderaadt case CHANCE:
155bb3b10f2Spjanzen chance();
156bb3b10f2Spjanzen break;
157df930be7Sderaadt case INC_TAX:
158bb3b10f2Spjanzen inc_tax();
159bb3b10f2Spjanzen break;
160df930be7Sderaadt case GOTO_J:
161bb3b10f2Spjanzen goto_jail();
162bb3b10f2Spjanzen break;
163df930be7Sderaadt case LUX_TAX:
164bb3b10f2Spjanzen lux_tax();
165bb3b10f2Spjanzen break;
166df930be7Sderaadt case PRPTY:
167df930be7Sderaadt case RR:
168df930be7Sderaadt case UTIL:
169df930be7Sderaadt if (sqp->owner < 0) {
170df930be7Sderaadt printf("That would cost $%d\n", sqp->cost);
171df930be7Sderaadt if (getyn("Do you want to buy? ") == 0) {
172df930be7Sderaadt buy(player, sqp);
173df930be7Sderaadt cur_p->money -= sqp->cost;
174df930be7Sderaadt }
175df930be7Sderaadt else if (num_play > 2)
176bb3b10f2Spjanzen bid();
177df930be7Sderaadt }
178df930be7Sderaadt else if (sqp->owner == player)
179df930be7Sderaadt printf("You own it.\n");
180df930be7Sderaadt else
181df930be7Sderaadt rent(sqp);
182df930be7Sderaadt }
183df930be7Sderaadt }
184bba3186fSpjanzen
185bba3186fSpjanzen
186bba3186fSpjanzen #define MONOP_TAG "monop(6) save file"
187df930be7Sderaadt /*
188df930be7Sderaadt * This routine saves the current game for use at a later date
189df930be7Sderaadt */
190bb3b10f2Spjanzen void
save(void)191211c4183Smestre save(void)
192bb3b10f2Spjanzen {
193bba3186fSpjanzen int i, j;
194df930be7Sderaadt time_t t;
195df930be7Sderaadt struct stat sb;
196bba3186fSpjanzen char *sp;
197bba3186fSpjanzen FILE *outf;
198df930be7Sderaadt
199df930be7Sderaadt printf("Which file do you wish to save it in? ");
200bb3b10f2Spjanzen getbuf();
201df930be7Sderaadt
202df930be7Sderaadt /*
203df930be7Sderaadt * check for existing files, and confirm overwrite if needed
204df930be7Sderaadt */
205bb3b10f2Spjanzen if (stat(buf, &sb) == 0
206bb3b10f2Spjanzen && getyn("File exists. Do you wish to overwrite? ") > 0)
207df930be7Sderaadt return;
208df930be7Sderaadt
209bba3186fSpjanzen umask(022);
210bba3186fSpjanzen if ((outf = fopen(buf, "w")) == NULL) {
211b638aa94Smillert warn("%s", buf);
212df930be7Sderaadt return;
213df930be7Sderaadt }
214df930be7Sderaadt printf("\"%s\" ", buf);
215df930be7Sderaadt time(&t); /* get current time */
216bba3186fSpjanzen fprintf(outf, "%s\n", MONOP_TAG);
217bba3186fSpjanzen fprintf(outf, "# %s", ctime(&t)); /* ctime() has \n */
218bba3186fSpjanzen fprintf(outf, "%d %d %d\n", num_play, player, num_doub);
219bba3186fSpjanzen for (i = 0; i < num_play; i++)
220bba3186fSpjanzen fprintf(outf, "%s\n", name_list[i]);
221bba3186fSpjanzen for (i = 0; i < num_play; i++)
222bba3186fSpjanzen fprintf(outf, "%d %d %d %d\n", play[i].money, play[i].loc,
223bba3186fSpjanzen play[i].num_gojf, play[i].in_jail);
224bba3186fSpjanzen /* Deck status */
225bba3186fSpjanzen for (i = 0; i < 2; i++) {
226bba3186fSpjanzen fprintf(outf, "%d %d %d\n", (int)(deck[i].num_cards),
227bba3186fSpjanzen (int)(deck[i].top_card), (int)(deck[i].gojf_used));
228bba3186fSpjanzen for (j = 0; j < deck[i].num_cards; j++)
229bba3186fSpjanzen fprintf(outf, "%ld ", (long)(deck[i].offsets[j]));
230bba3186fSpjanzen fprintf(outf, "\n");
231bba3186fSpjanzen }
232bba3186fSpjanzen /* Ownership */
233bba3186fSpjanzen for (i = 0; i < N_SQRS; i++) {
234bba3186fSpjanzen if (board[i].owner >= 0) {
235bba3186fSpjanzen if (board[i].type == PRPTY)
236bba3186fSpjanzen fprintf(outf, "%d %d %d %d\n", i, board[i].owner,
237bba3186fSpjanzen board[i].desc->morg, board[i].desc->houses);
238bba3186fSpjanzen else if (board[i].type == RR || board[i].type == UTIL)
239bba3186fSpjanzen fprintf(outf, "%d %d %d 0\n", i, board[i].owner,
240bba3186fSpjanzen board[i].desc->morg);
241bba3186fSpjanzen }
242bba3186fSpjanzen }
243bba3186fSpjanzen fclose(outf);
244bba3186fSpjanzen
24542ceebb3Sderaadt strlcpy(buf, ctime(&t), sizeof buf);
246df930be7Sderaadt for (sp = buf; *sp != '\n'; sp++)
247df930be7Sderaadt continue;
248df930be7Sderaadt *sp = '\0';
249df930be7Sderaadt printf("[%s]\n", buf);
250df930be7Sderaadt }
251df930be7Sderaadt /*
252bba3186fSpjanzen * If we are restoring during a game, try not to leak memory.
253bba3186fSpjanzen */
254bba3186fSpjanzen void
game_restore(void)255211c4183Smestre game_restore(void)
256bba3186fSpjanzen {
257bba3186fSpjanzen int i;
258bba3186fSpjanzen
2590affe7fcStedu free(play);
260bba3186fSpjanzen for (i = 0; i < num_play; i++)
261bba3186fSpjanzen free(name_list[i]);
262bba3186fSpjanzen restore();
263bba3186fSpjanzen }
264bba3186fSpjanzen /*
265df930be7Sderaadt * This routine restores an old game from a file
266df930be7Sderaadt */
267bb3b10f2Spjanzen void
restore(void)268211c4183Smestre restore(void)
269bb3b10f2Spjanzen {
270df930be7Sderaadt printf("Which file do you wish to restore from? ");
271bb3b10f2Spjanzen getbuf();
272bba3186fSpjanzen if (rest_f(buf) == FALSE) {
273bba3186fSpjanzen printf("Restore failed\n");
274bba3186fSpjanzen exit(1);
275bba3186fSpjanzen }
276df930be7Sderaadt }
277df930be7Sderaadt /*
278df930be7Sderaadt * This does the actual restoring. It returns TRUE if the
279bb3b10f2Spjanzen * backup was successful, else FALSE.
280df930be7Sderaadt */
281bb3b10f2Spjanzen int
rest_f(char * file)282211c4183Smestre rest_f(char *file)
283bb3b10f2Spjanzen {
284bb3b10f2Spjanzen char *sp;
285bba3186fSpjanzen int i, j, num;
286bba3186fSpjanzen FILE *inf;
287bba3186fSpjanzen char *st, *a, *b;
288*f3c23159Sop size_t linesize;
289*f3c23159Sop ssize_t len;
290df930be7Sderaadt STAT sbuf;
291bba3186fSpjanzen int t1;
292bba3186fSpjanzen short t2, t3, t4;
293bba3186fSpjanzen long tl;
294df930be7Sderaadt
295df930be7Sderaadt printf("\"%s\" ", file);
296df69c215Sderaadt if (stat(file, &sbuf) == -1) { /* get file stats */
297bba3186fSpjanzen warn("%s", file);
298bba3186fSpjanzen return(FALSE);
299df930be7Sderaadt }
300bba3186fSpjanzen if ((inf = fopen(file, "r")) == NULL) {
301bba3186fSpjanzen warn("%s", file);
302bba3186fSpjanzen return(FALSE);
303bba3186fSpjanzen }
304bba3186fSpjanzen
305bba3186fSpjanzen num = 1;
306*f3c23159Sop st = NULL;
307*f3c23159Sop linesize = 0;
308*f3c23159Sop len = getline(&st, &linesize, inf);
309*f3c23159Sop if (len == -1 || len != strlen(MONOP_TAG) + 1 ||
310bba3186fSpjanzen strncmp(st, MONOP_TAG, strlen(MONOP_TAG))) {
311bba3186fSpjanzen badness:
312bba3186fSpjanzen warnx("%s line %d", file, num);
313*f3c23159Sop free(st);
314bba3186fSpjanzen fclose(inf);
315bba3186fSpjanzen return(FALSE);
316bba3186fSpjanzen }
317bba3186fSpjanzen num++;
318*f3c23159Sop if (getline(&st, &linesize, inf) == -1)
319bba3186fSpjanzen goto badness;
320bba3186fSpjanzen num++;
321*f3c23159Sop if ((len = getline(&st, &linesize, inf)) == -1 || st[len - 1] != '\n')
322bba3186fSpjanzen goto badness;
323bba3186fSpjanzen st[len - 1] = '\0';
324bba3186fSpjanzen if (sscanf(st, "%d %d %d", &num_play, &player, &num_doub) != 3 ||
325bba3186fSpjanzen num_play > MAX_PL || num_play < 1 ||
326bba3186fSpjanzen player < 0 || player >= num_play ||
327bba3186fSpjanzen num_doub < 0 || num_doub > 2)
328bba3186fSpjanzen goto badness;
329ca161728Sderaadt if ((play = calloc(num_play, sizeof(PLAY))) == NULL)
330bba3186fSpjanzen err(1, NULL);
331bba3186fSpjanzen cur_p = play + player;
332bba3186fSpjanzen /* Names */
333bba3186fSpjanzen for (i = 0; i < num_play; i++) {
334bba3186fSpjanzen num++;
335*f3c23159Sop if ((len = getline(&st, &linesize, inf)) == -1 ||
336*f3c23159Sop st[len - 1] != '\n')
337bba3186fSpjanzen goto badness;
338bba3186fSpjanzen st[len - 1] = '\0';
339bba3186fSpjanzen if ((name_list[i] = play[i].name = strdup(st)) == NULL)
340bba3186fSpjanzen err(1, NULL);
341bba3186fSpjanzen }
342bba3186fSpjanzen if ((name_list[i++] = strdup("done")) == NULL)
343bba3186fSpjanzen err(1, NULL);
344bba3186fSpjanzen name_list[i] = NULL;
345bba3186fSpjanzen /* Money, location, GOJF cards, turns in jail */
346bba3186fSpjanzen for (i = 0; i < num_play; i++) {
347bba3186fSpjanzen num++;
348*f3c23159Sop if ((len = getline(&st, &linesize, inf)) == -1 ||
349*f3c23159Sop st[len - 1] != '\n')
350bba3186fSpjanzen goto badness;
351bba3186fSpjanzen st[len - 1] = '\0';
352bba3186fSpjanzen if (sscanf(st, "%d %hd %hd %hd", &(play[i].money), &t2,
353bba3186fSpjanzen &t3, &t4) != 4 ||
354bba3186fSpjanzen t2 < 0 || t2 > N_SQRS || t3 < 0 || t3 > 2 ||
355bba3186fSpjanzen (t2 != JAIL && t4 != 0) || t4 < 0 || t4 > 3)
356bba3186fSpjanzen goto badness;
357bba3186fSpjanzen play[i].loc = t2;
358bba3186fSpjanzen play[i].num_gojf = t3;
359bba3186fSpjanzen play[i].in_jail = t4;
360bba3186fSpjanzen }
361bba3186fSpjanzen /* Deck status; init_decks() must have been called. */
362bba3186fSpjanzen for (i = 0; i < 2; i++) {
363bba3186fSpjanzen num++;
364*f3c23159Sop if ((len = getline(&st, &linesize, inf)) == -1 ||
365*f3c23159Sop st[len - 1] != '\n')
366bba3186fSpjanzen goto badness;
367bba3186fSpjanzen st[len - 1] = '\0';
368bba3186fSpjanzen if (sscanf(st, "%d %d %hd", &t1, &j, &t2) != 3 ||
369bba3186fSpjanzen j > t1 || t1 != deck[i].num_cards || j < 0 ||
370bba3186fSpjanzen (t2 != FALSE && t2 != TRUE))
371bba3186fSpjanzen goto badness;
372bba3186fSpjanzen deck[i].top_card = j;
373bba3186fSpjanzen deck[i].gojf_used = t2;
374bba3186fSpjanzen num++;
375*f3c23159Sop if ((len = getline(&st, &linesize, inf)) == -1 ||
376*f3c23159Sop st[len - 1] != '\n')
377bba3186fSpjanzen goto badness;
378bba3186fSpjanzen st[len - 1] = '\0';
379bba3186fSpjanzen a = st;
380bba3186fSpjanzen for (j = 0; j < deck[i].num_cards; j++) {
381bba3186fSpjanzen if ((tl = strtol(a, &b, 10)) < 0 || tl >= 0x7FFFFFFF ||
382bba3186fSpjanzen b == a)
383bba3186fSpjanzen goto badness;
384bba3186fSpjanzen deck[i].offsets[j] = tl;
385bba3186fSpjanzen b = a;
386bba3186fSpjanzen }
387bba3186fSpjanzen /* Ignore anything trailing */
388bba3186fSpjanzen }
389bba3186fSpjanzen trading = FALSE;
390*f3c23159Sop while ((len = getline(&st, &linesize, inf)) != -1) {
391bba3186fSpjanzen num++;
392bba3186fSpjanzen if (st[len - 1] != '\n')
393bba3186fSpjanzen goto badness;
394bba3186fSpjanzen st[len - 1] = '\0';
395bba3186fSpjanzen /* Location, owner, mortgaged, nhouses */
396bba3186fSpjanzen if (sscanf(st, "%d %hd %hd %hd", &t1, &t2, &t3, &t4) != 4 ||
397bba3186fSpjanzen t1 < 0 || t1 >= N_SQRS || (board[t1].type != PRPTY &&
398bba3186fSpjanzen board[t1].type != RR && board[t1].type != UTIL) ||
399bba3186fSpjanzen t2 < 0 || t2 >= num_play ||
400bba3186fSpjanzen (t3 != TRUE && t3 != FALSE) ||
401bba3186fSpjanzen t4 < 0 || t4 > 5 || (t4 > 0 && t3 == TRUE))
402bba3186fSpjanzen goto badness;
403bba3186fSpjanzen add_list(t2, &(play[t2].own_list), t1);
404bba3186fSpjanzen /* No properties on mortgaged lots */
405bba3186fSpjanzen if (t3 && t4)
406bba3186fSpjanzen goto badness;
407bba3186fSpjanzen board[t1].owner = t2;
408bba3186fSpjanzen (board[t1].desc)->morg = t3;
409bba3186fSpjanzen (board[t1].desc)->houses = t4;
410bba3186fSpjanzen /* XXX Should check that number of houses per property are all
411bba3186fSpjanzen * within 1 in each monopoly
412bba3186fSpjanzen */
413bba3186fSpjanzen }
414*f3c23159Sop free(st);
415bba3186fSpjanzen fclose(inf);
416bba3186fSpjanzen /* Check total hotel and house count */
417bba3186fSpjanzen t1 = j = 0;
418bba3186fSpjanzen for (i = 0; i < N_SQRS; i++) {
419bba3186fSpjanzen if (board[i].type == PRPTY) {
420bba3186fSpjanzen if ((board[i].desc)->houses == 5)
421bba3186fSpjanzen j++;
422bba3186fSpjanzen else
423bba3186fSpjanzen t1 += (board[i].desc)->houses;
424bba3186fSpjanzen }
425bba3186fSpjanzen }
426bba3186fSpjanzen if (t1 > N_HOUSE || j > N_HOTEL) {
427bba3186fSpjanzen warnx("too many buildings");
428bba3186fSpjanzen return(FALSE);
429bba3186fSpjanzen }
430bba3186fSpjanzen /* Check GOJF cards */
431bba3186fSpjanzen t1 = 0;
432bba3186fSpjanzen for (i = 0; i < num_play; i++)
433bba3186fSpjanzen t1 += play[i].num_gojf;
434bba3186fSpjanzen for (i = 0; i < 2; i++)
435bba3186fSpjanzen t1 -= (deck[i].gojf_used == TRUE);
436bba3186fSpjanzen if (t1 != 0) {
437bba3186fSpjanzen warnx("can't figure out the Get-out-of-jail-free cards");
438bba3186fSpjanzen return(FALSE);
439bba3186fSpjanzen }
440bba3186fSpjanzen
44142ceebb3Sderaadt strlcpy(buf, ctime(&sbuf.st_mtime), sizeof buf);
442df930be7Sderaadt for (sp = buf; *sp != '\n'; sp++)
443df930be7Sderaadt continue;
444df930be7Sderaadt *sp = '\0';
445df930be7Sderaadt printf("[%s]\n", buf);
446bba3186fSpjanzen return(TRUE);
447df930be7Sderaadt }
448