diff options
author | Paul Janzen <pjanzen@cvs.openbsd.org> | 2002-07-28 08:44:15 +0000 |
---|---|---|
committer | Paul Janzen <pjanzen@cvs.openbsd.org> | 2002-07-28 08:44:15 +0000 |
commit | 50c9b42e6cc2fe234b971b4e514dc10cbd14c9e4 (patch) | |
tree | 7c00e1a13f7357fb9e22619ef4f7b5f75a4f4a9c /games/monop | |
parent | f8801812cc74de68362964ce13f511c11ad6f93a (diff) |
Tidy the code, follow the rules more closely (and document where we diverge),
and make save files work. The last stops a number of segfaults.
Diffstat (limited to 'games/monop')
-rw-r--r-- | games/monop/brd.dat | 66 | ||||
-rw-r--r-- | games/monop/cards.c | 73 | ||||
-rw-r--r-- | games/monop/deck.h | 4 | ||||
-rw-r--r-- | games/monop/execute.c | 254 | ||||
-rw-r--r-- | games/monop/getinp.c | 6 | ||||
-rw-r--r-- | games/monop/houses.c | 108 | ||||
-rw-r--r-- | games/monop/initdeck.c | 24 | ||||
-rw-r--r-- | games/monop/jail.c | 21 | ||||
-rw-r--r-- | games/monop/misc.c | 23 | ||||
-rw-r--r-- | games/monop/mon.dat | 26 | ||||
-rw-r--r-- | games/monop/monop.6 | 10 | ||||
-rw-r--r-- | games/monop/monop.c | 37 | ||||
-rw-r--r-- | games/monop/monop.def | 8 | ||||
-rw-r--r-- | games/monop/monop.h | 7 | ||||
-rw-r--r-- | games/monop/morg.c | 12 | ||||
-rw-r--r-- | games/monop/print.c | 18 | ||||
-rw-r--r-- | games/monop/prop.c | 34 | ||||
-rw-r--r-- | games/monop/rent.c | 17 | ||||
-rw-r--r-- | games/monop/roll.c | 25 | ||||
-rw-r--r-- | games/monop/spec.c | 6 | ||||
-rw-r--r-- | games/monop/trade.c | 19 |
21 files changed, 541 insertions, 257 deletions
diff --git a/games/monop/brd.dat b/games/monop/brd.dat index a6db0c2efbe..c0ff051a579 100644 --- a/games/monop/brd.dat +++ b/games/monop/brd.dat @@ -1,4 +1,4 @@ -/* $OpenBSD: brd.dat,v 1.2 1998/09/20 23:36:49 pjanzen Exp $ */ +/* $OpenBSD: brd.dat,v 1.3 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: brd.dat,v 1.2 1995/03/23 08:34:34 cgd Exp $ */ /*- @@ -38,44 +38,44 @@ /* name (COLOR) owner type desc cost */ -{"=== GO ===", -1, SAFE, 0 }, -{"Mediterranean ave. (P)", -1, PRPTY, &prop[0], 60 }, -{"Community Chest i", -1, CC, }, -{"Baltic ave. (P)", -1, PRPTY, &prop[1], 60 }, -{"Income Tax", -1, INC_TAX, }, +{"=== GO ===", -1, SAFE, 0, 0 }, +{"Mediterranean Ave. (P)", -1, PRPTY, &prop[0], 60 }, +{"Community Chest i", -1, CC, 0, 0 }, +{"Baltic Ave. (P)", -1, PRPTY, &prop[1], 60 }, +{"Income Tax", -1, INC_TAX,0, 0 }, {"Reading RR", -1, RR, &rr[0], 200 }, -{"Oriental ave. (L)", -1, PRPTY, &prop[2], 100 }, -{"Chance i", -1, CHANCE, }, -{"Vermont ave. (L)", -1, PRPTY, &prop[3], 100 }, -{"Connecticut ave. (L)", -1, PRPTY, &prop[4], 120 }, -{"Just Visiting", -1, SAFE, 0 }, +{"Oriental Ave. (L)", -1, PRPTY, &prop[2], 100 }, +{"Chance i", -1, CHANCE, 0, 0 }, +{"Vermont Ave. (L)", -1, PRPTY, &prop[3], 100 }, +{"Connecticut Ave. (L)", -1, PRPTY, &prop[4], 120 }, +{"Just Visiting", -1, SAFE, 0, 0 }, {"St. Charles pl. (V)", -1, PRPTY, &prop[5], 140 }, {"Electric Co.", -1, UTIL, &util[0], 150 }, -{"States ave. (V)", -1, PRPTY, &prop[6], 140 }, -{"Virginia ave. (V)", -1, PRPTY, &prop[7], 160 }, +{"States Ave. (V)", -1, PRPTY, &prop[6], 140 }, +{"Virginia Ave. (V)", -1, PRPTY, &prop[7], 160 }, {"Pennsylvania RR", -1, RR, &rr[1], 200 }, -{"St. James pl. (O)", -1, PRPTY, &prop[8], 180 }, -{"Community Chest ii", -1, CC, }, -{"Tennessee ave. (O)", -1, PRPTY, &prop[9], 180 }, -{"New York ave. (O)", -1, PRPTY, &prop[10], 200 }, -{"Free Parking", -1, SAFE, 0 }, -{"Kentucky ave. (R)", -1, PRPTY, &prop[11], 220 }, -{"Chance ii", -1, CHANCE, }, -{"Indiana ave. (R)", -1, PRPTY, &prop[12], 220 }, -{"Illinois ave. (R)", -1, PRPTY, &prop[13], 240 }, +{"St. James Pl. (O)", -1, PRPTY, &prop[8], 180 }, +{"Community Chest ii", -1, CC, 0, 0 }, +{"Tennessee Ave. (O)", -1, PRPTY, &prop[9], 180 }, +{"New York Ave. (O)", -1, PRPTY, &prop[10], 200 }, +{"Free Parking", -1, SAFE, 0, 0 }, +{"Kentucky Ave. (R)", -1, PRPTY, &prop[11], 220 }, +{"Chance ii", -1, CHANCE, 0, 0 }, +{"Indiana Ave. (R)", -1, PRPTY, &prop[12], 220 }, +{"Illinois Ave. (R)", -1, PRPTY, &prop[13], 240 }, {"B&O RR", -1, RR, &rr[2], 200 }, -{"Atlantic ave. (Y)", -1, PRPTY, &prop[14], 260 }, -{"Ventnor ave. (Y)", -1, PRPTY, &prop[15], 260 }, +{"Atlantic Ave. (Y)", -1, PRPTY, &prop[14], 260 }, +{"Ventnor Ave. (Y)", -1, PRPTY, &prop[15], 260 }, {"Water Works", -1, UTIL, &util[1], 150 }, {"Marvin Gardens (Y)", -1, PRPTY, &prop[16], 280 }, -{"GO TO JAIL", -1, GOTO_J, }, -{"Pacific ave. (G)", -1, PRPTY, &prop[17], 300 }, -{"N. Carolina ave. (G)", -1, PRPTY, &prop[18], 300 }, -{"Community Chest iii", -1, CC, }, -{"Pennsylvania ave. (G)", -1, PRPTY, &prop[19], 320 }, +{"GO TO JAIL", -1, GOTO_J, 0, 0 }, +{"Pacific Ave. (G)", -1, PRPTY, &prop[17], 300 }, +{"N. Carolina Ave. (G)", -1, PRPTY, &prop[18], 300 }, +{"Community Chest iii", -1, CC, 0, 0 }, +{"Pennsylvania Ave. (G)", -1, PRPTY, &prop[19], 320 }, {"Short Line RR", -1, RR, &rr[3], 200 }, -{"Chance iii", -1, CHANCE, }, -{"Park place (D)", -1, PRPTY, &prop[20], 350 }, -{"Luxury Tax", -1, LUX_TAX, }, +{"Chance iii", -1, CHANCE, 0, 0 }, +{"Park Place (D)", -1, PRPTY, &prop[20], 350 }, +{"Luxury Tax", -1, LUX_TAX,0, 0 }, {"Boardwalk (D)", -1, PRPTY, &prop[21], 400 }, -{"JAIL", -1, IN_JAIL, } +{"JAIL", -1, IN_JAIL,0, 0 } diff --git a/games/monop/cards.c b/games/monop/cards.c index 9d36bad9e0b..cc658247394 100644 --- a/games/monop/cards.c +++ b/games/monop/cards.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cards.c,v 1.5 2002/02/16 21:27:10 millert Exp $ */ +/* $OpenBSD: cards.c,v 1.6 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: cards.c,v 1.3 1995/03/23 08:34:35 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)cards.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: cards.c,v 1.5 2002/02/16 21:27:10 millert Exp $"; +static const char rcsid[] = "$OpenBSD: cards.c,v 1.6 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -52,11 +52,7 @@ static char rcsid[] = "$OpenBSD: cards.c,v 1.5 2002/02/16 21:27:10 millert Exp $ #define GOJF 'F' /* char for get-out-of-jail-free cards */ -#ifndef DEV static char *cardfile = _PATH_CARDS; -#else -static char *cardfile = "cards.pck"; -#endif static FILE *deckf; @@ -75,21 +71,21 @@ file_err: err(1, "%s", cardfile); if (fread(&deck[0].num_cards, sizeof(deck[0].num_cards), 1, deckf) != 1) goto file_err; - if (fread(&deck[0].last_card, sizeof(deck[0].last_card), 1, deckf) != 1) + if (fread(&deck[0].top_card, sizeof(deck[0].top_card), 1, deckf) != 1) goto file_err; if (fread(&deck[0].gojf_used, sizeof(deck[0].gojf_used), 1, deckf) != 1) goto file_err; deck[0].num_cards = ntohs(deck[0].num_cards); - deck[0].last_card = ntohs(deck[0].last_card); + deck[0].top_card = ntohs(deck[0].top_card); if (fread(&deck[1].num_cards, sizeof(deck[1].num_cards), 1, deckf) != 1) goto file_err; - if (fread(&deck[1].last_card, sizeof(deck[1].last_card), 1, deckf) != 1) + if (fread(&deck[1].top_card, sizeof(deck[1].top_card), 1, deckf) != 1) goto file_err; if (fread(&deck[1].gojf_used, sizeof(deck[1].gojf_used), 1, deckf) != 1) goto file_err; deck[1].num_cards = ntohs(deck[1].num_cards); - deck[1].last_card = ntohs(deck[1].last_card); + deck[1].top_card = ntohs(deck[1].top_card); set_up(&CC_D); set_up(&CH_D); @@ -105,13 +101,13 @@ set_up(dp) int i; if ((dp->offsets = (int32_t *) calloc(sizeof (int32_t), dp->num_cards)) == NULL) - errx(1, "malloc"); + err(1, NULL); for (i = 0 ; i < dp->num_cards ; i++) { if (fread(&dp->offsets[i], sizeof(dp->offsets[i]), 1, deckf) != 1) err(1, "%s", cardfile); dp->offsets[i] = ntohl(dp->offsets[i]); } - dp->last_card = 0; + dp->top_card = 0; dp->gojf_used = FALSE; for (i = 0; i < dp->num_cards; i++) { long temp; @@ -136,8 +132,8 @@ get_card(dp) OWN *op; do { - fseek(deckf, dp->offsets[dp->last_card], 0); - dp->last_card = ++(dp->last_card) % dp->num_cards; + fseek(deckf, dp->offsets[dp->top_card], SEEK_SET); + dp->top_card = ++(dp->top_card) % dp->num_cards; type_maj = getc(deckf); } while (dp->gojf_used && type_maj == GOJF); type_min = getc(deckf); @@ -224,6 +220,7 @@ get_card(dp) } spec = FALSE; } + /* * This routine prints out the message on the card */ @@ -239,3 +236,51 @@ printmes() printline(); fflush(stdout); } + +/* + * This routine returns the players get-out-of-jail-free card + * to the bottom of a deck. XXX currently does not return to the correct + * deck. + */ +void +ret_card(plr) + PLAY *plr; +{ + char type_maj; + int16_t gojfpos, last_card; + int i; + DECK *dp; + int32_t temp; + + plr->num_gojf--; + if (CC_D.gojf_used) + dp = &CC_D; + else + dp = &CH_D; + dp->gojf_used = FALSE; + + /* Put at bottom of deck (top_card - 1) and remove it from wherever else + * it used to be. + */ + last_card = dp->top_card - 1; + if (last_card < 0) + last_card += dp->num_cards; + gojfpos = dp->top_card; + do { + gojfpos = (gojfpos + 1) % dp->num_cards; + fseek(deckf, dp->offsets[gojfpos], SEEK_SET); + type_maj = getc(deckf); + } while (type_maj != GOJF); + temp = dp->offsets[gojfpos]; + /* Only one of the next two loops does anything */ + for (i = gojfpos - 1; i > last_card; i--) + dp->offsets[i + 1] = dp->offsets[i]; + for (i = gojfpos; i < last_card; i++) + dp->offsets[i] = dp->offsets[i + 1]; + if (gojfpos > last_card) { + dp->offsets[dp->top_card] = temp; + dp->top_card++; + dp->top_card %= dp->num_cards; + } else + dp->offsets[last_card] = temp; +} diff --git a/games/monop/deck.h b/games/monop/deck.h index 4e22f512db3..461afedd4fd 100644 --- a/games/monop/deck.h +++ b/games/monop/deck.h @@ -1,4 +1,4 @@ -/* $OpenBSD: deck.h,v 1.3 1998/09/20 23:36:50 pjanzen Exp $ */ +/* $OpenBSD: deck.h,v 1.4 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: deck.h,v 1.3 1995/03/23 08:34:36 cgd Exp $ */ /* @@ -45,7 +45,7 @@ struct dk_st { /* deck description structure */ int16_t num_cards; /* number of cards in deck */ - int16_t last_card; /* number of last card picked */ + int16_t top_card; /* number of last card picked */ bool gojf_used; /* set if gojf card out of deck */ int32_t *offsets; /* offsets for start of cards */ }; diff --git a/games/monop/execute.c b/games/monop/execute.c index 2e5746a3f09..5b82eca5c1d 100644 --- a/games/monop/execute.c +++ b/games/monop/execute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: execute.c,v 1.5 2002/02/16 21:27:10 millert Exp $ */ +/* $OpenBSD: execute.c,v 1.6 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: execute.c,v 1.3 1995/03/23 08:34:38 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)execute.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: execute.c,v 1.5 2002/02/16 21:27:10 millert Exp $"; +static const char rcsid[] = "$OpenBSD: execute.c,v 1.6 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -51,8 +51,6 @@ static char rcsid[] = "$OpenBSD: execute.c,v 1.5 2002/02/16 21:27:10 millert Exp #include <stdlib.h> #include <unistd.h> -#define SEGSIZE 8192 - typedef struct stat STAT; typedef struct tm TIME; @@ -71,9 +69,9 @@ getbuf() char *sp; int tmpin, i; - i = 0; + i = 1; sp = buf; - while (((tmpin = getchar()) != '\n') && (i < sizeof(buf)) && + while (((tmpin = getchar()) != '\n') && (i < (int)sizeof(buf)) && (tmpin != EOF)) { *sp++ = tmpin; i++; @@ -157,7 +155,7 @@ show_move() { SQUARE *sqp; - sqp = &board[cur_p->loc]; + sqp = &board[(int)cur_p->loc]; printf("That puts you on %s\n", sqp->name); switch (sqp->type) { case SAFE: @@ -196,17 +194,20 @@ show_move() rent(sqp); } } + + +#define MONOP_TAG "monop(6) save file" /* * This routine saves the current game for use at a later date */ void save() { - char *sp; - int outf, num; - time_t t; - struct stat sb; - char *start, *end; + int i, j; + time_t t; + struct stat sb; + char *sp; + FILE *outf; printf("Which file do you wish to save it in? "); getbuf(); @@ -214,35 +215,65 @@ save() /* * check for existing files, and confirm overwrite if needed */ - if (stat(buf, &sb) == 0 && getyn("File exists. Do you wish to overwrite? ") > 0) return; - if ((outf=creat(buf, 0644)) < 0) { + umask(022); + if ((outf = fopen(buf, "w")) == NULL) { warn("%s", buf); return; } printf("\"%s\" ", buf); time(&t); /* get current time */ + fprintf(outf, "%s\n", MONOP_TAG); + fprintf(outf, "# %s", ctime(&t)); /* ctime() has \n */ + fprintf(outf, "%d %d %d\n", num_play, player, num_doub); + for (i = 0; i < num_play; i++) + fprintf(outf, "%s\n", name_list[i]); + for (i = 0; i < num_play; i++) + fprintf(outf, "%d %d %d %d\n", play[i].money, play[i].loc, + play[i].num_gojf, play[i].in_jail); + /* Deck status */ + for (i = 0; i < 2; i++) { + fprintf(outf, "%d %d %d\n", (int)(deck[i].num_cards), + (int)(deck[i].top_card), (int)(deck[i].gojf_used)); + for (j = 0; j < deck[i].num_cards; j++) + fprintf(outf, "%ld ", (long)(deck[i].offsets[j])); + fprintf(outf, "\n"); + } + /* Ownership */ + for (i = 0; i < N_SQRS; i++) { + if (board[i].owner >= 0) { + if (board[i].type == PRPTY) + fprintf(outf, "%d %d %d %d\n", i, board[i].owner, + board[i].desc->morg, board[i].desc->houses); + else if (board[i].type == RR || board[i].type == UTIL) + fprintf(outf, "%d %d %d 0\n", i, board[i].owner, + board[i].desc->morg); + } + } + fclose(outf); + strcpy(buf, ctime(&t)); for (sp = buf; *sp != '\n'; sp++) continue; *sp = '\0'; -#if 0 - start = (((int) etext + (SEGSIZE-1)) / SEGSIZE ) * SEGSIZE; -#else - start = 0; -#endif - end = sbrk(0); - while (start < end) { /* write out entire data space */ - num = start + 16 * 1024 > end ? end - start : 16 * 1024; - write(outf, start, num); - start += num; - } - close(outf); printf("[%s]\n", buf); } +/* + * If we are restoring during a game, try not to leak memory. + */ +void +game_restore() +{ + int i; + + cfree(play); + for (i = 0; i < num_play; i++) + free(name_list[i]); + restore(); +} /* * This routine restores an old game from a file */ @@ -251,7 +282,10 @@ restore() { printf("Which file do you wish to restore from? "); getbuf(); - rest_f(buf); + if (rest_f(buf) == FALSE) { + printf("Restore failed\n"); + exit(1); + } } /* * This does the actual restoring. It returns TRUE if the @@ -261,34 +295,158 @@ int rest_f(file) char *file; { - char *sp; - int inf, num; - char *start, *end; - STAT sbuf; + char *sp; + int i, j, num; + FILE *inf; + char *st, *a, *b; + size_t len; + STAT sbuf; + int t1; + short t2, t3, t4; + long tl; - if ((inf = open(file, O_RDONLY)) < 0) { + printf("\"%s\" ", file); + if (stat(file, &sbuf) < 0) { /* get file stats */ warn("%s", file); - return FALSE; + return(FALSE); } - printf("\"%s\" ", file); - if (fstat(inf, &sbuf) < 0) /* get file stats */ - err(1, "%s", file); -#if 0 - start = (((int) etext + (SEGSIZE-1)) / SEGSIZE ) * SEGSIZE; -#else - start = 0; -#endif - brk(end = start + sbuf.st_size); - while (start < end) { /* write out entire data space */ - num = start + 16 * 1024 > end ? end - start : 16 * 1024; - read(inf, start, num); - start += num; + if ((inf = fopen(file, "r")) == NULL) { + warn("%s", file); + return(FALSE); + } + + num = 1; + st = fgetln(inf, &len); + if (st == NULL || len != strlen(MONOP_TAG) + 1 || + strncmp(st, MONOP_TAG, strlen(MONOP_TAG))) { +badness: + warnx("%s line %d", file, num); + fclose(inf); + return(FALSE); + } + num++; + if (fgetln(inf, &len) == NULL) + goto badness; + num++; + if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n') + goto badness; + st[len - 1] = '\0'; + if (sscanf(st, "%d %d %d", &num_play, &player, &num_doub) != 3 || + num_play > MAX_PL || num_play < 1 || + player < 0 || player >= num_play || + num_doub < 0 || num_doub > 2) + goto badness; + if ((play = (PLAY *)calloc(num_play, sizeof(PLAY))) == NULL) + err(1, NULL); + cur_p = play + player; + /* Names */ + for (i = 0; i < num_play; i++) { + num++; + if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n') + goto badness; + st[len - 1] = '\0'; + if ((name_list[i] = play[i].name = strdup(st)) == NULL) + err(1, NULL); } - close(inf); + if ((name_list[i++] = strdup("done")) == NULL) + err(1, NULL); + name_list[i] = NULL; + /* Money, location, GOJF cards, turns in jail */ + for (i = 0; i < num_play; i++) { + num++; + if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n') + goto badness; + st[len - 1] = '\0'; + if (sscanf(st, "%d %hd %hd %hd", &(play[i].money), &t2, + &t3, &t4) != 4 || + t2 < 0 || t2 > N_SQRS || t3 < 0 || t3 > 2 || + (t2 != JAIL && t4 != 0) || t4 < 0 || t4 > 3) + goto badness; + play[i].loc = t2; + play[i].num_gojf = t3; + play[i].in_jail = t4; + } + /* Deck status; init_decks() must have been called. */ + for (i = 0; i < 2; i++) { + num++; + if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n') + goto badness; + st[len - 1] = '\0'; + if (sscanf(st, "%d %d %hd", &t1, &j, &t2) != 3 || + j > t1 || t1 != deck[i].num_cards || j < 0 || + (t2 != FALSE && t2 != TRUE)) + goto badness; + deck[i].top_card = j; + deck[i].gojf_used = t2; + num++; + if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n') + goto badness; + st[len - 1] = '\0'; + a = st; + for (j = 0; j < deck[i].num_cards; j++) { + if ((tl = strtol(a, &b, 10)) < 0 || tl >= 0x7FFFFFFF || + b == a) + goto badness; + deck[i].offsets[j] = tl; + b = a; + } + /* Ignore anything trailing */ + } + trading = FALSE; + while ((st = fgetln(inf, &len)) != NULL) { + num++; + if (st[len - 1] != '\n') + goto badness; + st[len - 1] = '\0'; + /* Location, owner, mortgaged, nhouses */ + if (sscanf(st, "%d %hd %hd %hd", &t1, &t2, &t3, &t4) != 4 || + t1 < 0 || t1 >= N_SQRS || (board[t1].type != PRPTY && + board[t1].type != RR && board[t1].type != UTIL) || + t2 < 0 || t2 >= num_play || + (t3 != TRUE && t3 != FALSE) || + t4 < 0 || t4 > 5 || (t4 > 0 && t3 == TRUE)) + goto badness; + add_list(t2, &(play[t2].own_list), t1); + /* No properties on mortgaged lots */ + if (t3 && t4) + goto badness; + board[t1].owner = t2; + (board[t1].desc)->morg = t3; + (board[t1].desc)->houses = t4; + /* XXX Should check that number of houses per property are all + * within 1 in each monopoly + */ + } + fclose(inf); + /* Check total hotel and house count */ + t1 = j = 0; + for (i = 0; i < N_SQRS; i++) { + if (board[i].type == PRPTY) { + if ((board[i].desc)->houses == 5) + j++; + else + t1 += (board[i].desc)->houses; + } + } + if (t1 > N_HOUSE || j > N_HOTEL) { + warnx("too many buildings"); + return(FALSE); + } + /* Check GOJF cards */ + t1 = 0; + for (i = 0; i < num_play; i++) + t1 += play[i].num_gojf; + for (i = 0; i < 2; i++) + t1 -= (deck[i].gojf_used == TRUE); + if (t1 != 0) { + warnx("can't figure out the Get-out-of-jail-free cards"); + return(FALSE); + } + strcpy(buf, ctime(&sbuf.st_mtime)); for (sp = buf; *sp != '\n'; sp++) continue; *sp = '\0'; printf("[%s]\n", buf); - return TRUE; + return(TRUE); } diff --git a/games/monop/getinp.c b/games/monop/getinp.c index a8bf164f547..98d108b07a8 100644 --- a/games/monop/getinp.c +++ b/games/monop/getinp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getinp.c,v 1.5 2002/02/16 21:27:10 millert Exp $ */ +/* $OpenBSD: getinp.c,v 1.6 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: getinp.c,v 1.4 1995/04/24 12:24:20 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)getinp.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: getinp.c,v 1.5 2002/02/16 21:27:10 millert Exp $"; +static const char rcsid[] = "$OpenBSD: getinp.c,v 1.6 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -67,7 +67,7 @@ getinp(prompt, list) printf("user closed input stream, quitting...\n"); exit(0); } - if (buf[0] == '?' && buf[1] == '\n') { + if (buf[0] == '?' /* && buf[1] == '\n' */ ) { printf("Valid inputs are: "); for (i = 0, match = 18; list[i]; i++) { if ((match += (n_match = strlen(list[i]))) > LINE) { diff --git a/games/monop/houses.c b/games/monop/houses.c index 3b089ff3773..a033011e734 100644 --- a/games/monop/houses.c +++ b/games/monop/houses.c @@ -1,4 +1,4 @@ -/* $OpenBSD: houses.c,v 1.3 2002/02/16 21:27:10 millert Exp $ */ +/* $OpenBSD: houses.c,v 1.4 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: houses.c,v 1.3 1995/03/23 08:34:40 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)houses.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: houses.c,v 1.3 2002/02/16 21:27:10 millert Exp $"; +static const char rcsid[] = "$OpenBSD: houses.c,v 1.4 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -52,6 +52,9 @@ static MON *monops[N_MON]; static void buy_h(MON *); static void sell_h(MON *); static void list_cur(MON *); +static int avail_houses(); +static int avail_hotels(); +static bool can_only_buy_hotel(MON *); /* * These routines deal with buying and selling houses @@ -62,7 +65,7 @@ buy_houses() int num_mon; MON *mp; OWN *op; - bool good,got_morg; + bool good, got_morg; int i,p; over: @@ -79,9 +82,9 @@ over: got_morg = good = FALSE; for (i = 0; i < mp->num_in; i++) { if (op->sqr->desc->morg) - got_morg++; + got_morg = TRUE; if (op->sqr->desc->houses != 5) - good++; + good = TRUE; op = op->next; } if (!good || got_morg) @@ -118,11 +121,24 @@ buy_h(mnp) MON *mp; int price; shrt input[3],temp[3]; - int tot; + int tot, tot2; PROP *pp; + int nhous, nhot; + bool chot; mp = mnp; price = mp->h_cost * 50; + nhous = avail_houses(); + nhot = avail_hotels(); + chot = can_only_buy_hotel(mnp); + if (nhous == 0 && !chot) { + printf("Building shortage: no houses available."); + return; + } + if (nhot == 0 && chot) { + printf("Building shortage: no hotels available."); + return; + } blew_it: list_cur(mp); printf("Houses will cost $%d\n", price); @@ -136,7 +152,7 @@ over: temp[i] = 5; continue; } - (void)sprintf(cur_prop, "%s (%d): ", + (void)snprintf(cur_prop, sizeof(cur_prop), "%s (%d): ", mp->sq[i]->name, pp->houses); input[i] = get_int(cur_prop); temp[i] = input[i] + pp->houses; @@ -153,10 +169,27 @@ err: printf("That makes the spread too wide. Try again\n"); } else if (mp->num_in == 2 && abs(temp[0] - temp[1]) > 1) goto err; - for (tot = i = 0; i < mp->num_in; i++) - tot += input[i]; + for (tot = tot2 = i = 0; i < mp->num_in; i++) { + if (temp[i] == 5) + tot2++; + else + tot += input[i]; + } + if (tot > nhous) { + printf( +"You have asked for %d house%s but only %d are available. Try again\n", + tot, tot == 1 ? "":"s", nhous); + goto blew_it; + } else if (tot2 > nhot) { + printf( +"You have asked for %d hotel%s but only %d are available. Try again\n", + tot2, tot2 == 1 ? "":"s", nhot); + goto blew_it; + } + if (tot) { - printf("You asked for %d houses for $%d\n", tot, tot * price); + printf("You asked for %d house%s and %d hotel%s for $%d\n", tot, + tot == 1 ? "" : "s", tot2, tot2 == 1 ? "" : "s", tot * price); if (getyn("Is that ok? ") == 0) { cur_p->money -= tot * price; for (tot = i = 0; i < mp->num_in; i++) @@ -237,10 +270,11 @@ over: continue; } if (pp->houses < 5) - (void)sprintf(cur_prop,"%s (%d): ", + (void)snprintf(cur_prop, sizeof(cur_prop), "%s (%d): ", mp->sq[i]->name,pp->houses); else - (void)sprintf(cur_prop,"%s (H): ",mp->sq[i]->name); + (void)snprintf(cur_prop, sizeof(cur_prop), "%s (H): ", + mp->sq[i]->name); input[i] = get_int(cur_prop); temp[i] = pp->houses - input[i]; if (temp[i] < 0) { @@ -258,7 +292,8 @@ err: printf("That makes the spread too wide. Try again\n"); for (tot = i = 0; i < mp->num_in; i++) tot += input[i]; if (tot) { - printf("You asked to sell %d houses for $%d\n",tot,tot * price); + printf("You asked to sell %d house%s for $%d\n", tot, + tot == 1 ? "" : "s", tot * price); if (getyn("Is that ok? ") == 0) { cur_p->money += tot * price; for (tot = i = 0; i < mp->num_in; i++) @@ -283,3 +318,50 @@ list_cur(mp) } putchar('\n'); } + +static int +avail_houses() +{ + int i, c; + SQUARE *sqp; + + c = 0; + for (i = 0; i < N_SQRS; i++) { + sqp = &board[i]; + if (sqp->type == PRPTY && sqp->owner >= 0 && sqp->desc->monop) { + if (sqp->desc->houses < 5 && sqp->desc->houses > 0) + c += sqp->desc->houses; + } + } + return(N_HOUSE - c); +} + +static int +avail_hotels() +{ + int i, c; + SQUARE *sqp; + + c = 0; + for (i = 0; i < N_SQRS; i++) { + sqp = &board[i]; + if (sqp->type == PRPTY && sqp->owner >= 0 && sqp->desc->monop) { + if (sqp->desc->houses == 5) + c++; + } + } + return(N_HOTEL - c); +} + +static bool +can_only_buy_hotel(mp) + MON *mp; +{ + int i; + + for (i = 0; i < mp->num_in; i++) { + if (mp->sq[i]->desc->houses < 4) + return(FALSE); + } + return(TRUE); +} diff --git a/games/monop/initdeck.c b/games/monop/initdeck.c index 8f844ad4223..f698b4aaea1 100644 --- a/games/monop/initdeck.c +++ b/games/monop/initdeck.c @@ -1,4 +1,4 @@ -/* $OpenBSD: initdeck.c,v 1.10 2002/05/31 03:40:01 pjanzen Exp $ */ +/* $OpenBSD: initdeck.c,v 1.11 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: initdeck.c,v 1.3 1995/03/23 08:34:43 cgd Exp $ */ /* @@ -35,7 +35,7 @@ */ #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1980, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ @@ -44,7 +44,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)initdeck.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: initdeck.c,v 1.10 2002/05/31 03:40:01 pjanzen Exp $"; +static const char rcsid[] = "$OpenBSD: initdeck.c,v 1.11 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -99,17 +99,17 @@ main(ac, av) sizeof (int32_t))) == NULL || (CH_D.offsets = (int32_t *)calloc(CH_D.num_cards + 1, sizeof (int32_t))) == NULL) - errx(1, "malloc"); - fseek(inf, 0L, 0); + err(1, NULL); + fseek(inf, 0L, SEEK_SET); if ((outf = fopen(outfile, "w")) == NULL) err(1, "%s", outfile); fwrite(&deck[0].num_cards, sizeof(deck[0].num_cards), 1, outf); - fwrite(&deck[0].last_card, sizeof(deck[0].last_card), 1, outf); + fwrite(&deck[0].top_card, sizeof(deck[0].top_card), 1, outf); fwrite(&deck[0].gojf_used, sizeof(deck[0].gojf_used), 1, outf); fwrite(&deck[0].num_cards, sizeof(deck[0].num_cards), 1, outf); - fwrite(&deck[0].last_card, sizeof(deck[0].last_card), 1, outf); + fwrite(&deck[0].top_card, sizeof(deck[0].top_card), 1, outf); fwrite(&deck[0].gojf_used, sizeof(deck[0].gojf_used), 1, outf); fwrite(CC_D.offsets, sizeof(CC_D.offsets[0]), CC_D.num_cards, outf); @@ -117,19 +117,19 @@ main(ac, av) putem(); fclose(inf); - fseek(outf, 0, 0L); + fseek(outf, 0L, SEEK_SET); deck[0].num_cards = htons(deck[0].num_cards); fwrite(&deck[0].num_cards, sizeof(deck[0].num_cards), 1, outf); - deck[0].last_card = htons(deck[0].last_card); - fwrite(&deck[0].last_card, sizeof(deck[0].last_card), 1, outf); + deck[0].top_card = htons(deck[0].top_card); + fwrite(&deck[0].top_card, sizeof(deck[0].top_card), 1, outf); fwrite(&deck[0].gojf_used, sizeof(deck[0].gojf_used), 1, outf); deck[0].num_cards = ntohs(deck[0].num_cards); deck[1].num_cards = htons(deck[1].num_cards); fwrite(&deck[1].num_cards, sizeof(deck[1].num_cards), 1, outf); - deck[1].last_card = htons(deck[1].last_card); - fwrite(&deck[1].last_card, sizeof(deck[1].last_card), 1, outf); + deck[1].top_card = htons(deck[1].top_card); + fwrite(&deck[1].top_card, sizeof(deck[1].top_card), 1, outf); fwrite(&deck[1].gojf_used, sizeof(deck[1].gojf_used), 1, outf); deck[1].num_cards = ntohs(deck[1].num_cards); diff --git a/games/monop/jail.c b/games/monop/jail.c index 665c4c20d7c..8ddabe1996c 100644 --- a/games/monop/jail.c +++ b/games/monop/jail.c @@ -1,4 +1,4 @@ -/* $OpenBSD: jail.c,v 1.2 1998/09/20 23:36:51 pjanzen Exp $ */ +/* $OpenBSD: jail.c,v 1.3 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: jail.c,v 1.3 1995/03/23 08:34:44 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)jail.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: jail.c,v 1.2 1998/09/20 23:36:51 pjanzen Exp $"; +static const char rcsid[] = "$OpenBSD: jail.c,v 1.3 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -64,20 +64,6 @@ card() cur_p->in_jail = 0; } /* - * This routine returns the players get-out-of-jail-free card - * to a deck. - */ -void -ret_card(plr) - PLAY *plr; -{ - plr->num_gojf--; - if (CC_D.gojf_used) - CC_D.gojf_used = FALSE; - else - CH_D.gojf_used = FALSE; -} -/* * This routine deals with paying your way out of jail. */ void @@ -112,8 +98,7 @@ moveit: return TRUE; } return FALSE; - } - else { + } else { printf("Double roll gets you out.\n"); goto moveit; } diff --git a/games/monop/misc.c b/games/monop/misc.c index bbb5cdc0ae8..c554efd7bc1 100644 --- a/games/monop/misc.c +++ b/games/monop/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.4 2001/01/17 00:27:21 pjanzen Exp $ */ +/* $OpenBSD: misc.c,v 1.5 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: misc.c,v 1.4 1995/03/23 08:34:47 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: misc.c,v 1.4 2001/01/17 00:27:21 pjanzen Exp $"; +static const char rcsid[] = "$OpenBSD: misc.c,v 1.5 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -95,7 +95,7 @@ int get_int(prompt) char *prompt; { - int num; + int num, snum; char *sp; int c, i; char buf[257]; @@ -103,14 +103,14 @@ get_int(prompt) for (;;) { printf(prompt); num = 0; - i = 0; + i = 1; for (sp = buf; (c = getchar()) != '\n';) { if (c == EOF) { printf("user closed input stream, quitting...\n"); exit(0); } *sp = c; - if (i < sizeof(buf)) { + if (i < (int)sizeof(buf)) { i++; sp++; } @@ -119,9 +119,18 @@ get_int(prompt) if (sp == buf) continue; for (sp = buf; isspace(*sp); sp++) - continue; - for (; isdigit(*sp); sp++) + ; + for (; isdigit(*sp); sp++) { + snum = num; num = num * 10 + *sp - '0'; + if (num < snum) { + printf("Number too large - "); + *(sp + 1) = 'X'; /* Force a break */ + } + } + /* Be kind to trailing spaces */ + for (; *sp == ' '; sp++) + ; if (*sp == '\n') return num; else diff --git a/games/monop/mon.dat b/games/monop/mon.dat index 87647e06464..be840193179 100644 --- a/games/monop/mon.dat +++ b/games/monop/mon.dat @@ -1,4 +1,4 @@ -/* $OpenBSD: mon.dat,v 1.2 1998/09/20 23:36:51 pjanzen Exp $ */ +/* $OpenBSD: mon.dat,v 1.3 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: mon.dat,v 1.2 1995/03/23 08:34:49 cgd Exp $ */ /*- @@ -37,11 +37,19 @@ */ /* name owner num_in num_own h_cost not_m mon_n sq */ -{0, -1, 2, 0, 1, "Purple", "PURPLE", {1,3}}, -{0, -1, 3, 0, 1, "Lt. Blue", "LT. BLUE", {6,8,9}}, -{0, -1, 3, 0, 2, "Violet", "VIOLET", {11,13,14}}, -{0, -1, 3, 0, 2, "Orange", "ORANGE", {16,18,19}}, -{0, -1, 3, 0, 3, "Red", "RED", {21,23,24}}, -{0, -1, 3, 0, 3, "Yellow", "YELLOW", {26,27,29}}, -{0, -1, 3, 0, 4, "Green", "GREEN", {31,32,34}}, -{0, -1, 2, 0, 4, "Dk. Blue", "DK. BLUE", {37,39}} +{0, -1, 2, 0, 1, "Purple", "PURPLE", {1,3}, +{NULL, NULL, NULL}}, +{0, -1, 3, 0, 1, "Lt. Blue", "LT. BLUE", {6,8,9}, +{NULL, NULL, NULL}}, +{0, -1, 3, 0, 2, "Violet", "VIOLET", {11,13,14}, +{NULL, NULL, NULL}}, +{0, -1, 3, 0, 2, "Orange", "ORANGE", {16,18,19}, +{NULL, NULL, NULL}}, +{0, -1, 3, 0, 3, "Red", "RED", {21,23,24}, +{NULL, NULL, NULL}}, +{0, -1, 3, 0, 3, "Yellow", "YELLOW", {26,27,29}, +{NULL, NULL, NULL}}, +{0, -1, 3, 0, 4, "Green", "GREEN", {31,32,34}, +{NULL, NULL, NULL}}, +{0, -1, 2, 0, 4, "Dk. Blue", "DK. BLUE", {37,39}, +{NULL, NULL, NULL}} diff --git a/games/monop/monop.6 b/games/monop/monop.6 index a4480e03fb3..755bdc74431 100644 --- a/games/monop/monop.6 +++ b/games/monop/monop.6 @@ -1,4 +1,4 @@ -.\" $OpenBSD: monop.6,v 1.8 2001/11/17 05:27:09 pjanzen Exp $ +.\" $OpenBSD: monop.6,v 1.9 2002/07/28 08:44:14 pjanzen Exp $ .\" .\" Copyright (c) 1980 The Regents of the University of California. .\" All rights reserved. @@ -182,4 +182,10 @@ Ken Arnold .Sh BUGS No command can be given an argument instead of a response to a query. .Pp -While saving a game works pretty well, restoring one does not. +Additional cash cannot be generated during an auction by selling buildings +or by mortgaging property. +.Pp +The trading of mortgaged properties is not billed correctly. +.Pp +Resigning to the bank should trigger the immediate auction of all +possessions. diff --git a/games/monop/monop.c b/games/monop/monop.c index 2266be4137a..d26c7e06e9d 100644 --- a/games/monop/monop.c +++ b/games/monop/monop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monop.c,v 1.4 2002/02/16 21:27:10 millert Exp $ */ +/* $OpenBSD: monop.c,v 1.5 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: monop.c,v 1.3 1995/03/23 08:34:52 cgd Exp $ */ /* @@ -35,7 +35,7 @@ */ #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1980, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ @@ -44,12 +44,11 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)monop.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: monop.c,v 1.4 2002/02/16 21:27:10 millert Exp $"; +static const char rcsid[] = "$OpenBSD: monop.c,v 1.5 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ #include <err.h> -#include <signal.h> #include <stdlib.h> #include <unistd.h> #include "monop.def" @@ -57,7 +56,6 @@ static char rcsid[] = "$OpenBSD: monop.c,v 1.4 2002/02/16 21:27:10 millert Exp $ static void getplayers(void); static void init_players(void); static void init_monops(void); -static void do_quit(int); /* * This program implements a monopoly game @@ -68,6 +66,9 @@ main(ac, av) char *av[]; { srandom(getpid()); + num_luck = sizeof lucky_mes / sizeof (char *); + init_decks(); + init_monops(); if (ac > 1) { if (!rest_f(av[1])) restore(); @@ -75,26 +76,16 @@ main(ac, av) else { getplayers(); init_players(); - init_monops(); } - num_luck = sizeof lucky_mes / sizeof (char *); - init_decks(); - signal(SIGQUIT, do_quit); for (;;) { printf("\n%s (%d) (cash $%d) on %s\n", cur_p->name, player + 1, - cur_p->money, board[cur_p->loc].name); + cur_p->money, board[(int)cur_p->loc].name); printturn(); force_morg(); execute(getinp("-- Command: ", comlist)); } } -static void -do_quit(n) - int n; -{ - quit(); -} /* * This routine gets the names of the players */ @@ -109,12 +100,13 @@ blew_it: for (;;) { if ((num_play = get_int("How many players? ")) <= 1 || num_play > MAX_PL) - printf("Sorry. Number must range from 2 to 9\n"); + printf("Sorry. Number must range from 2 to %d\n", + MAX_PL); else break; } if ((cur_p = play = (PLAY *) calloc(num_play, sizeof (PLAY))) == NULL) - errx(1, "malloc"); + err(1, NULL); for (i = 0; i < num_play; i++) { do { printf("Player %d's name: ", i + 1); @@ -127,9 +119,8 @@ blew_it: if (*sp == '\n') *sp = '\0'; } while (strlen(buf) == 0); - if ((name_list[i] = play[i].name = (char *)calloc(1, sizeof(buf))) == NULL) - errx(1, "malloc"); - strcpy(name_list[i], buf); + if ((name_list[i] = play[i].name = strdup(buf)) == NULL) + err(1, NULL); play[i].money = 1500; } name_list[i++] = "done"; @@ -142,7 +133,7 @@ blew_it: else printf("\"done\" is a reserved word. Please try again\n"); for (i = 0; i < num_play; i++) - cfree(play[i].name); + free(play[i].name); cfree(play); goto blew_it; } @@ -190,6 +181,6 @@ init_monops() for (mp = mon; mp < &mon[N_MON]; mp++) { mp->name = mp->not_m; for (i = 0; i < mp->num_in; i++) - mp->sq[i] = &board[mp->sqnums[i]]; + mp->sq[i] = &board[(int)mp->sqnums[i]]; } } diff --git a/games/monop/monop.def b/games/monop/monop.def index 0fb4614cfd7..7ef84835bd8 100644 --- a/games/monop/monop.def +++ b/games/monop/monop.def @@ -1,4 +1,4 @@ -/* $OpenBSD: monop.def,v 1.3 2002/02/16 21:27:10 millert Exp $ */ +/* $OpenBSD: monop.def,v 1.4 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: monop.def,v 1.3 1995/03/23 08:34:54 cgd Exp $ */ /*- @@ -39,8 +39,8 @@ #include "deck.h" #include "monop.h" -bool fixing, /* set if fixing up debt */ - trading, /* set if in process of trading */ +bool fixing = FALSE, /* set if fixing up debt */ + trading = FALSE, /* set if in process of trading */ told_em, /* set if told user he's out of debt */ spec; /* set if moving by card to RR or UTIL */ @@ -96,7 +96,7 @@ void (*func[])(void) = { /* array of function calls for commands */ trade, /* trade |* 11 *| */ resign, /* resign |* 12 *| */ save, /* save game |* 13 *| */ - restore, /* restore game |* 14 *| */ + game_restore, /* restore game |* 14 *| */ do_move, /* roll |* 15 *| */ do_move /* "" |* 16 *| */ }; diff --git a/games/monop/monop.h b/games/monop/monop.h index 7a2bb5b7db7..1815a11af2e 100644 --- a/games/monop/monop.h +++ b/games/monop/monop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monop.h,v 1.5 2002/02/16 21:27:10 millert Exp $ */ +/* $OpenBSD: monop.h,v 1.6 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: monop.h,v 1.4 1995/04/24 12:24:23 cgd Exp $ */ /* @@ -57,6 +57,8 @@ #define N_SQRS 40 /* number of squares on board */ #define MAX_PL 9 /* maximum number of players */ #define MAX_PRP (N_PROP+N_RR+N_UTIL) /* max # ownable property */ +#define N_HOUSE 32 /* total number of houses available */ +#define N_HOTEL 12 /* total number of hotels available */ /* square type numbers */ #define PRPTY 0 /* normal property */ @@ -139,6 +141,7 @@ typedef struct prp_st UTIL_S; /* cards.c */ void init_decks(void); void get_card(DECK *); +void ret_card(PLAY *); /* execute.c */ void execute(int); @@ -146,6 +149,7 @@ void do_move(void); void move(int); void save(void); void restore(void); +void game_restore(void); int rest_f(char *); /* getinp.c */ @@ -157,7 +161,6 @@ void sell_houses(void); /* jail.c */ void card(void); -void ret_card(PLAY *); void pay(void); int move_jail(int, int ); void printturn(void); diff --git a/games/monop/morg.c b/games/monop/morg.c index d9e1b30af96..35ec9414187 100644 --- a/games/monop/morg.c +++ b/games/monop/morg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: morg.c,v 1.3 2002/02/16 21:27:11 millert Exp $ */ +/* $OpenBSD: morg.c,v 1.4 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: morg.c,v 1.4 1995/03/23 08:35:02 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)morg.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: morg.c,v 1.3 2002/02/16 21:27:11 millert Exp $"; +static const char rcsid[] = "$OpenBSD: morg.c,v 1.4 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -70,7 +70,7 @@ static char *names[MAX_PRP+2], static shrt square[MAX_PRP+2]; -static int num_good,got_houses; +static int num_good, got_houses; static int set_mlist(void); static void m(int); @@ -207,15 +207,15 @@ unm(prop) } /* * This routine forces the indebted player to fix his - * financial woes. + * financial woes. It is fine to have $0 but not to be in debt. */ void force_morg() { told_em = fixing = TRUE; - while (cur_p->money <= 0) { + while (cur_p->money < 0) { told_em = FALSE; - (*func[(getinp("How are you going to fix it up? ",morg_coms))])(); + (*func[(getinp("How are you going to fix it up? ", morg_coms))])(); notify(); } fixing = FALSE; diff --git a/games/monop/print.c b/games/monop/print.c index b66e9e48d41..b2ef5cb622c 100644 --- a/games/monop/print.c +++ b/games/monop/print.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print.c,v 1.3 2002/02/16 21:27:11 millert Exp $ */ +/* $OpenBSD: print.c,v 1.4 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: print.c,v 1.3 1995/03/23 08:35:05 cgd Exp $ */ /* @@ -38,13 +38,13 @@ #if 0 static char sccsid[] = "@(#)print.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: print.c,v 1.3 2002/02/16 21:27:11 millert Exp $"; +static const char rcsid[] = "$OpenBSD: print.c,v 1.4 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ #include "monop.ext" -static char *header = "Name Own Price Mg # Rent"; +static const char *header = "Name Own Price Mg # Rent"; static void printmorg(SQUARE *); @@ -120,7 +120,7 @@ printsq(sqn, eoln) if (pp->houses < 5) { if (pp->houses > 0) printf("%d %4d", pp->houses, - pp->rent[pp->houses]); + pp->rent[(int)pp->houses]); else printf("0 %4d", pp->rent[0] * 2); } else @@ -137,7 +137,7 @@ printsq(sqn, eoln) } printf(" %d 150", sqp->owner+1); printmorg(sqp); - printf("%d", play[sqp->owner].num_util); + printf("%d", play[(int)sqp->owner].num_util); if (!eoln) printf(" "); break; @@ -151,8 +151,12 @@ printsq(sqn, eoln) printf(" %d Railroad 200", sqp->owner+1); printmorg(sqp); rnt = 25; - rnt <<= play[sqp->owner].num_rr - 1; - printf("%d %4d", play[sqp->owner].num_rr, 25 << (play[sqp->owner].num_rr - 1)); + rnt <<= play[(int)sqp->owner].num_rr - 1; + printf("%d %4d", play[(int)sqp->owner].num_rr, + 25 << (play[(int)sqp->owner].num_rr - 1)); + break; + default: + printf("Warning: printsq() switch %d\n", sqp->type); break; } if (eoln) diff --git a/games/monop/prop.c b/games/monop/prop.c index 441ac90aab1..69e3cf48420 100644 --- a/games/monop/prop.c +++ b/games/monop/prop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: prop.c,v 1.4 2002/02/16 21:27:11 millert Exp $ */ +/* $OpenBSD: prop.c,v 1.5 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: prop.c,v 1.3 1995/03/23 08:35:06 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)prop.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: prop.c,v 1.4 2002/02/16 21:27:11 millert Exp $"; +static const char rcsid[] = "$OpenBSD: prop.c,v 1.5 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -52,13 +52,13 @@ static int value(SQUARE *); * appropriate flags. */ void -buy(player, sqrp) - int player; +buy(plr, sqrp) + int plr; SQUARE *sqrp; { trading = FALSE; - sqrp->owner = player; - add_list(player, &(play[player].own_list), cur_p->loc); + sqrp->owner = plr; + add_list(plr, &(play[plr].own_list), cur_p->loc); } /* * This routine adds an item to the list. @@ -74,7 +74,7 @@ add_list(plr, head, op_sqr) OWN *op; if ((op = (OWN *)calloc(1, sizeof (OWN))) == NULL) - errx(1, "malloc"); + err(1, NULL); op->sqr = &board[op_sqr]; val = value(op->sqr); last_tp = NULL; @@ -104,9 +104,9 @@ del_list(plr, head, op_sqr) { OWN *op, *last_op; - switch (board[op_sqr].type) { + switch (board[(int)op_sqr].type) { case PRPTY: - board[op_sqr].desc->mon_desc->num_own--; + board[(int)op_sqr].desc->mon_desc->num_own--; break; case RR: play[plr].num_rr--; @@ -117,7 +117,7 @@ del_list(plr, head, op_sqr) } last_op = NULL; for (op = *head; op; op = op->next) - if (op->sqr == &board[op_sqr]) + if (op->sqr == &board[(int)op_sqr]) break; else last_op = op; @@ -156,8 +156,7 @@ value(sqp) } } /* - * This routine accepts bids for the current peice - * of property. + * This routine accepts bids for the current piece of property. */ void bid() @@ -177,16 +176,19 @@ bid() i = (i + 1) % num_play; if (in[i]) { do { - (void)sprintf(buf, "%s: ", name_list[i]); + (void)snprintf(buf, sizeof(buf), "%s: ", name_list[i]); cur_bid = get_int(buf); if (cur_bid == 0) { in[i] = FALSE; if (--num_in == 0) break; - } - else if (cur_bid <= cur_max) { + } else if (cur_bid <= cur_max) { printf("You must bid higher than %d to stay in\n", cur_max); printf("(bid of 0 drops you out)\n"); + } else if (cur_bid > play[i].money) { + printf("You can't bid more than your cash ($%d)\n", + play[i].money); + cur_bid = -1; } } while (cur_bid != 0 && cur_bid <= cur_max); cur_max = (cur_bid ? cur_bid : cur_max); @@ -196,7 +198,7 @@ bid() while (!in[i]) i = (i + 1) % num_play; printf("It goes to %s (%d) for $%d\n",play[i].name,i+1,cur_max); - buy(i, &board[cur_p->loc]); + buy(i, &board[(int)cur_p->loc]); play[i].money -= cur_max; } else diff --git a/games/monop/rent.c b/games/monop/rent.c index 6fc85de61cb..fa47f6d8801 100644 --- a/games/monop/rent.c +++ b/games/monop/rent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rent.c,v 1.2 1998/09/20 23:36:55 pjanzen Exp $ */ +/* $OpenBSD: rent.c,v 1.3 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: rent.c,v 1.3 1995/03/23 08:35:11 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)rent.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: rent.c,v 1.2 1998/09/20 23:36:55 pjanzen Exp $"; +static const char rcsid[] = "$OpenBSD: rent.c,v 1.3 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -55,7 +55,7 @@ rent(sqp) PROP *pp; PLAY *plp; - plp = &play[sqp->owner]; + plp = &play[(int)sqp->owner]; printf("Owned by %s\n", plp->name); if (sqp->desc->morg) { lucky("The thing is mortgaged. "); @@ -68,11 +68,12 @@ rent(sqp) if (pp->houses == 0) printf("rent is %d\n", rnt = pp->rent[0] * 2); else if (pp->houses < 5) - printf("with %d houses, rent is %d\n", - pp->houses, rnt = pp->rent[pp->houses]); + printf("with %d house%s, rent is %d\n", + pp->houses, pp->houses == 1 ? "" : "s", + rnt = pp->rent[(int)pp->houses]); else printf("with a hotel, rent is %d\n", - rnt = pp->rent[pp->houses]); + rnt = pp->rent[(int)pp->houses]); } else printf("rent is %d\n", rnt = pp->rent[0]); break; @@ -94,6 +95,10 @@ rent(sqp) rnt *= 4; } break; + default: /* Should never be reached */ + rnt = 0; + printf("Warning: rent() property %d\n", sqp->type); + break; } cur_p->money -= rnt; plp->money += rnt; diff --git a/games/monop/roll.c b/games/monop/roll.c index 476f1ed18aa..7df4042801b 100644 --- a/games/monop/roll.c +++ b/games/monop/roll.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roll.c,v 1.2 1998/09/20 23:36:56 pjanzen Exp $ */ +/* $OpenBSD: roll.c,v 1.3 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: roll.c,v 1.5 1995/03/23 08:35:13 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)roll.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: roll.c,v 1.2 1998/09/20 23:36:56 pjanzen Exp $"; +static const char rcsid[] = "$OpenBSD: roll.c,v 1.3 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -47,26 +47,6 @@ static char rcsid[] = "$OpenBSD: roll.c,v 1.2 1998/09/20 23:36:56 pjanzen Exp $" /* * This routine rolls ndie nside-sided dice. */ - -#if defined(pdp11) -#define MAXRAND 32767L - -int -roll(ndie, nsides) - int ndie, nsides; -{ - long tot; - unsigned n, r; - - tot = 0; - n = ndie; - while (n--) - tot += random(); - return (int) ((tot * (long) nsides) / ((long) MAXRAND + 1)) + ndie; -} - -#else - int roll(ndie, nsides) int ndie, nsides; @@ -80,4 +60,3 @@ roll(ndie, nsides) tot += (r = random()) * (num_sides / RAND_MAX) + 1; return tot; } -#endif diff --git a/games/monop/spec.c b/games/monop/spec.c index 1df305197ae..b5b283bec80 100644 --- a/games/monop/spec.c +++ b/games/monop/spec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: spec.c,v 1.2 1998/09/20 23:36:56 pjanzen Exp $ */ +/* $OpenBSD: spec.c,v 1.3 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: spec.c,v 1.3 1995/03/23 08:35:16 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)spec.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: spec.c,v 1.2 1998/09/20 23:36:56 pjanzen Exp $"; +static const char rcsid[] = "$OpenBSD: spec.c,v 1.3 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -53,7 +53,7 @@ inc_tax() /* collect income tax */ { int worth, com_num; - com_num = getinp("Do you wish to lose 10%% of your total worth or $200? ", perc); + com_num = getinp("Do you wish to lose 10% of your total worth or $200? ", perc); worth = cur_p->money + prop_worth(cur_p); printf("You were worth $%d", worth); worth /= 10; diff --git a/games/monop/trade.c b/games/monop/trade.c index 75c206da790..5a5a7d5cdae 100644 --- a/games/monop/trade.c +++ b/games/monop/trade.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trade.c,v 1.3 2002/02/16 21:27:11 millert Exp $ */ +/* $OpenBSD: trade.c,v 1.4 2002/07/28 08:44:14 pjanzen Exp $ */ /* $NetBSD: trade.c,v 1.3 1995/03/23 08:35:19 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)trade.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: trade.c,v 1.3 2002/02/16 21:27:11 millert Exp $"; +static const char rcsid[] = "$OpenBSD: trade.c,v 1.4 2002/07/28 08:44:14 pjanzen Exp $"; #endif #endif /* not lint */ @@ -245,11 +245,14 @@ resign() SQUARE *sqp; if (cur_p->money <= 0) { - switch (board[cur_p->loc].type) { + switch (board[(int)cur_p->loc].type) { case UTIL: case RR: case PRPTY: - new_own = board[cur_p->loc].owner; + new_own = board[(int)cur_p->loc].owner; + /* If you ran out of money by buying current location */ + if (new_own == player) + new_own = num_play; break; default: /* Chance, taxes, etc */ new_own = num_play; @@ -305,16 +308,20 @@ resign() if (cur_p->num_gojf) ret_card(cur_p); } + free(name_list[player]); for (i = player; i < num_play; i++) { name_list[i] = name_list[i+1]; if (i + 1 < num_play) play[i] = play[i+1]; } - name_list[num_play--] = 0; + name_list[num_play--] = NULL; for (i = 0; i < N_SQRS; i++) if (board[i].owner > player) --board[i].owner; - player = --player < 0 ? num_play - 1 : player; + if (player == 0) + player = num_play - 1; + else + player--; next_play(); if (num_play < 2) { printf("\nThen %s WINS!!!!!\n", play[0].name); |