[BACK]Return to monop.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / games / monop

Annotation of src/games/monop/monop.c, Revision 1.23

1.23    ! dholland    1: /*     $NetBSD: monop.c,v 1.22 2008/02/24 03:56:49 christos Exp $      */
1.3       cgd         2:
1.1       cgd         3: /*
1.3       cgd         4:  * Copyright (c) 1980, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
1.14      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        16:  *    may be used to endorse or promote products derived from this software
                     17:  *    without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  */
                     31:
1.4       christos   32: #include <sys/cdefs.h>
1.1       cgd        33: #ifndef lint
1.4       christos   34: __COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
                     35:        The Regents of the University of California.  All rights reserved.\n");
1.1       cgd        36: #endif /* not lint */
                     37:
                     38: #ifndef lint
1.3       cgd        39: #if 0
                     40: static char sccsid[] = "@(#)monop.c    8.1 (Berkeley) 5/31/93";
                     41: #else
1.23    ! dholland   42: __RCSID("$NetBSD: monop.c,v 1.22 2008/02/24 03:56:49 christos Exp $");
1.3       cgd        43: #endif
1.1       cgd        44: #endif /* not lint */
                     45:
1.4       christos   46: #include <stdio.h>
                     47: #include <signal.h>
                     48: #include <stdlib.h>
1.18      dholland   49: #include <time.h>
1.4       christos   50: #include <unistd.h>
1.21      dholland   51: #include "deck.h"
                     52: #include "monop.h"
1.4       christos   53:
1.15      jsm        54: int main(int, char *[]);
                     55: static void getplayers(void);
                     56: static void init_players(void);
                     57: static void init_monops(void);
                     58: static void do_quit(int);
1.1       cgd        59:
1.21      dholland   60:
                     61: bool   fixing,                 /* set if fixing up debt                */
                     62:        trading,                /* set if in process of trading         */
                     63:        told_em,                /* set if told user he's out of debt    */
                     64:        spec;                   /* set if moving by card to RR or UTIL  */
                     65:
                     66: const char     *name_list[MAX_PL+2],   /* list of players' names       */
                     67:        *const comlist[]        = {     /* list of normal commands      */
                     68:        "quit",         /*  0 */        "print",        /*  1 */
                     69:        "where",        /*  2 */        "own holdings", /*  3 */
                     70:        "holdings",     /*  4 */        "mortgage",     /*  5 */
                     71:        "unmortgage",   /*  6 */        "buy houses",   /*  7 */
                     72:        "sell houses",  /*  8 */        "card",         /*  9 */
                     73:        "pay",          /* 10 */        "trade",        /* 11 */
                     74:        "resign",       /* 12 */        "save",         /* 13 */
                     75:        "restore",      /* 14 */        "roll",         /* 15 */
                     76:        "",             /* 16 */
                     77:        0
                     78:        },
                     79:        *const yncoms[] = {     /* list of commands for yes/no answers  */
                     80:        "yes",          /*  0 */        "no",           /*  1 */
                     81:        "quit",         /*  2 */        "print",        /*  3 */
                     82:        "where",        /*  4 */        "own holdings", /*  5 */
                     83:        "holdings",     /*  6 */
                     84:        0
                     85:        },
                     86:        *const lucky_mes[]      = {     /* "got lucky" messages         */
                     87:        "You lucky stiff",              "You got lucky",
                     88:        "What a lucky person!",         "You must have a 4-leaf clover",
                     89:        "My, my!  Aren't we lucky!",    "Luck smiles upon you",
                     90:        "You got lucky this time",      "Lucky person!",
                     91:        "Your karma must certainly be together",
                     92:        "How beautifully Cosmic",       "Wow, you must be really with it"
                     93:        /* "I want your autograph",     -- Save for later */
                     94:        };
                     95:
                     96: int    player,                 /* current player number                */
                     97:        num_play,               /* current number of players            */
                     98:        num_doub,               /* # of doubles current player rolled   */
                     99:                                /* # of "got lucky" messages            */
                    100:        num_luck        = sizeof lucky_mes / sizeof (char *);
                    101:
                    102: /* list of command functions           */
                    103: void (*const func[])(void) = { /* array of function calls for commands */
                    104:        quit,                   /* quit game            |*  0 *|        */
                    105:        printboard,             /* print board          |*  1 *|        */
                    106:        where,                  /* where players are    |*  2 *|        */
                    107:        list,                   /* own holdings         |*  3 *|        */
                    108:        list_all,               /* holdings list        |*  4 *|        */
                    109:        mortgage,               /* mortgage property    |*  5 *|        */
                    110:        unmortgage,             /* unmortgage property  |*  6 *|        */
                    111:        buy_houses,             /* buy houses           |*  7 *|        */
                    112:        sell_houses,            /* sell houses          |*  8 *|        */
                    113:        card,                   /* card for jail        |*  9 *|        */
                    114:        pay,                    /* pay for jail         |* 10 *|        */
                    115:        trade,                  /* trade                |* 11 *|        */
                    116:        resign,                 /* resign               |* 12 *|        */
                    117:        save,                   /* save game            |* 13 *|        */
                    118:        restore,                /* restore game         |* 14 *|        */
                    119:        do_move,                /* roll                 |* 15 *|        */
                    120:        do_move                 /* ""                   |* 16 *|        */
                    121:        };
                    122:
                    123: DECK   deck[2];                /* Chance and Community Chest           */
                    124:
                    125: PLAY   *play,                  /* player structure array ("calloc"ed)  */
                    126:        *cur_p;                 /* pointer to current player's struct   */
                    127:
                    128: RR_S   rr[N_RR];               /* railroad descriptions                */
                    129:
                    130: UTIL_S util[2];                /* utility descriptions                 */
                    131:
                    132: #define MONINIT(num_in, h_cost, not_m, mon_n, sq1,sq2,sq3) \
                    133:      {0,    -1, num_in, 0,      h_cost, not_m, mon_n, {sq1,sq2,sq3}, {0,0,0}}
                    134: /* name  owner          num_own                                      sq */
                    135:
                    136: MON    mon[N_MON]      = {     /* monopoly descriptions                */
                    137: /*   num_in h_cost  not_m      mon_n       sqnums */
                    138: MONINIT(2,  1, "Purple",       "PURPLE",   1,3, 0),
                    139: MONINIT(3,  1, "Lt. Blue",     "LT. BLUE", 6,8,9),
                    140: MONINIT(3,  2, "Violet",       "VIOLET",   11,13,14),
                    141: MONINIT(3,  2, "Orange",       "ORANGE",   16,18,19),
                    142: MONINIT(3,  3, "Red",          "RED",      21,23,24),
                    143: MONINIT(3,  3, "Yellow",       "YELLOW",   26,27,29),
                    144: MONINIT(3,  4, "Green",        "GREEN",    31,32,34),
                    145: MONINIT(2,  4, "Dk. Blue",     "DK. BLUE", 37,39, 0),
                    146: };
                    147: #undef MONINIT
                    148:
                    149: PROP   prop[N_PROP]    = {     /* typical properties                   */
                    150: /* morg        monop   square  houses  mon_desc        rent    */
                    151: {0,    0,      1,      0,      &mon[0],        { 2, 10, 30,  90, 160, 250} },
                    152: {0,    0,      3,      0,      &mon[0],        { 4, 20, 60, 180, 320, 450} },
                    153: {0,    0,      6,      0,      &mon[1],        { 6, 30, 90, 270, 400, 550} },
                    154: {0,    0,      7,      0,      &mon[1],        { 6, 30, 90, 270, 400, 550} },
                    155: {0,    0,      9,      0,      &mon[1],        { 8, 40,100, 300, 450, 600} },
                    156: {0,    0,      11,     0,      &mon[2],        {10, 50,150, 450, 625, 750} },
                    157: {0,    0,      13,     0,      &mon[2],        {10, 50,150, 450, 625, 750} },
                    158: {0,    0,      14,     0,      &mon[2],        {12, 60,180, 500, 700, 900} },
                    159: {0,    0,      16,     0,      &mon[3],        {14, 70,200, 550, 750, 950} },
                    160: {0,    0,      17,     0,      &mon[3],        {14, 70,200, 550, 750, 950} },
                    161: {0,    0,      19,     0,      &mon[3],        {16, 80,220, 600, 800,1000} },
                    162: {0,    0,      21,     0,      &mon[4],        {18, 90,250, 700, 875,1050} },
                    163: {0,    0,      23,     0,      &mon[4],        {18, 90,250, 700, 875,1050} },
                    164: {0,    0,      24,     0,      &mon[4],        {20,100,300, 750, 925,1100} },
                    165: {0,    0,      26,     0,      &mon[5],        {22,110,330, 800, 975,1150} },
                    166: {0,    0,      27,     0,      &mon[5],        {22,110,330, 800, 975,1150} },
                    167: {0,    0,      29,     0,      &mon[5],        {24,120,360, 850,1025,1200} },
                    168: {0,    0,      31,     0,      &mon[6],        {26,130,390, 900,1100,1275} },
                    169: {0,    0,      32,     0,      &mon[6],        {26,130,390, 900,1100,1275} },
                    170: {0,    0,      34,     0,      &mon[6],        {28,150,450,1000,1200,1400} },
                    171: {0,    0,      37,     0,      &mon[7],        {35,175,500,1100,1300,1500} },
                    172: {0,    0,      39,     0,      &mon[7],        {50,200,600,1400,1700,2000} }
                    173: };
                    174:
                    175: SQUARE board[N_SQRS+1] = {     /* board itself (+1 for Jail)           */
                    176: /* name (COLOR)                        owner   type    desc            cost    */
                    177:
                    178: {"=== GO ===",                 -1,     SAFE,   NULL,           0       },
                    179: {"Mediterranean Ave. (P)",     -1,     PRPTY,  &prop[0],       60      },
                    180: {"Community Chest i",          -1,     CC,     NULL,           0       },
                    181: {"Baltic Ave. (P)",            -1,     PRPTY,  &prop[1],       60      },
                    182: {"Income Tax",                 -1,     INC_TAX, NULL,          0       },
                    183: {"Reading RR",                 -1,     RR,     &rr[0],         200     },
                    184: {"Oriental Ave. (L)",          -1,     PRPTY,  &prop[2],       100     },
                    185: {"Chance i",                   -1,     CHANCE, NULL,           0       },
                    186: {"Vermont Ave. (L)",           -1,     PRPTY,  &prop[3],       100     },
                    187: {"Connecticut Ave. (L)",       -1,     PRPTY,  &prop[4],       120     },
                    188: {"Just Visiting",              -1,     SAFE,   NULL,           0       },
                    189: {"St. Charles Pl. (V)",                -1,     PRPTY,  &prop[5],       140     },
                    190: {"Electric Co.",               -1,     UTIL,   &util[0],       150     },
                    191: {"States Ave. (V)",            -1,     PRPTY,  &prop[6],       140     },
                    192: {"Virginia Ave. (V)",          -1,     PRPTY,  &prop[7],       160     },
                    193: {"Pennsylvania RR",            -1,     RR,     &rr[1],         200     },
                    194: {"St. James Pl. (O)",          -1,     PRPTY,  &prop[8],       180     },
                    195: {"Community Chest ii",         -1,     CC,     NULL,           0       },
                    196: {"Tennessee Ave. (O)",         -1,     PRPTY,  &prop[9],       180     },
                    197: {"New York Ave. (O)",          -1,     PRPTY,  &prop[10],      200     },
                    198: {"Free Parking",               -1,     SAFE,   NULL,           0       },
                    199: {"Kentucky Ave. (R)",          -1,     PRPTY,  &prop[11],      220     },
                    200: {"Chance ii",                  -1,     CHANCE, NULL,           0       },
                    201: {"Indiana Ave. (R)",           -1,     PRPTY,  &prop[12],      220     },
                    202: {"Illinois Ave. (R)",          -1,     PRPTY,  &prop[13],      240     },
                    203: {"B&O RR",                     -1,     RR,     &rr[2],         200     },
                    204: {"Atlantic Ave. (Y)",          -1,     PRPTY,  &prop[14],      260     },
                    205: {"Ventnor Ave. (Y)",           -1,     PRPTY,  &prop[15],      260     },
                    206: {"Water Works",                        -1,     UTIL,   &util[1],       150     },
                    207: {"Marvin Gardens (Y)",         -1,     PRPTY,  &prop[16],      280     },
                    208: {"GO TO JAIL",                 -1,     GOTO_J, NULL,           0       },
                    209: {"Pacific Ave. (G)",           -1,     PRPTY,  &prop[17],      300     },
                    210: {"N. Carolina Ave. (G)",       -1,     PRPTY,  &prop[18],      300     },
                    211: {"Community Chest iii",                -1,     CC,     NULL,           0       },
                    212: {"Pennsylvania Ave. (G)",      -1,     PRPTY,  &prop[19],      320     },
                    213: {"Short Line RR",              -1,     RR,     &rr[3],         200     },
                    214: {"Chance iii",                 -1,     CHANCE, NULL,           0       },
                    215: {"Park Place (D)",             -1,     PRPTY,  &prop[20],      350     },
                    216: {"Luxury Tax",                 -1,     LUX_TAX, NULL,          0       },
                    217: {"Boardwalk (D)",              -1,     PRPTY,  &prop[21],      400     },
                    218: {"JAIL",                       -1,     IN_JAIL, NULL,          0       }
                    219: };
                    220:
                    221:
1.1       cgd       222: /*
                    223:  *     This program implements a monopoly game
                    224:  */
1.4       christos  225: int
1.1       cgd       226: main(ac, av)
1.6       simonb    227:        int ac;
                    228:        char *av[];
                    229: {
1.9       jsm       230:        /* Revoke setgid privileges */
1.11      mycroft   231:        setgid(getgid());
1.9       jsm       232:
1.22      christos  233:        srandom((unsigned long)time(NULL));
1.19      dholland  234:        num_luck = sizeof lucky_mes / sizeof (char *);
                    235:        init_decks();
                    236:        init_monops();
1.1       cgd       237:        if (ac > 1) {
1.23    ! dholland  238:                if (rest_f(av[1]) < 0)
1.1       cgd       239:                        restore();
                    240:        }
                    241:        else {
                    242:                getplayers();
                    243:                init_players();
                    244:        }
1.5       hubertf   245:        signal(SIGINT, do_quit);
1.1       cgd       246:        for (;;) {
                    247:                printf("\n%s (%d) (cash $%d) on %s\n", cur_p->name, player + 1,
                    248:                        cur_p->money, board[cur_p->loc].name);
                    249:                printturn();
                    250:                force_morg();
                    251:                execute(getinp("-- Command: ", comlist));
                    252:        }
                    253: }
1.4       christos  254:
                    255: /*ARGSUSED*/
                    256: static void
                    257: do_quit(n)
1.16      perry     258:        int n __unused;
1.4       christos  259: {
                    260:        quit();
                    261: }
1.6       simonb    262:
1.1       cgd       263: /*
                    264:  *     This routine gets the names of the players
                    265:  */
1.4       christos  266: static void
                    267: getplayers()
                    268: {
1.6       simonb    269:        int i, j;
                    270:        char buf[257];
1.1       cgd       271:
                    272: blew_it:
                    273:        for (;;) {
1.19      dholland  274:                if ((num_play = get_int("How many players? ")) <= 1 ||
1.1       cgd       275:                    num_play > MAX_PL)
1.19      dholland  276:                        printf("Sorry. Number must range from 2 to %d\n",
                    277:                            MAX_PL);
1.1       cgd       278:                else
                    279:                        break;
                    280:        }
1.22      christos  281:        cur_p = play = calloc((size_t)num_play, sizeof (PLAY));
1.8       jsm       282:        if (play == NULL)
1.10      jsm       283:                err(1, NULL);
1.1       cgd       284:        for (i = 0; i < num_play; i++) {
1.19      dholland  285:                do {
                    286:                        printf("Player %d's name: ", i + 1);
                    287:                        fgets(buf, sizeof(buf), stdin);
                    288:                        if (feof(stdin)) {
                    289:                                printf("End of file on stdin\n");
                    290:                                exit(0);
                    291:                        }
                    292:                        buf[strcspn(buf, "\n")] = '\0';
                    293:                } while (strlen(buf) == 0);
                    294:                name_list[i] = play[i].name = strdup(buf);
1.8       jsm       295:                if (name_list[i] == NULL)
1.10      jsm       296:                        err(1, NULL);
1.1       cgd       297:                play[i].money = 1500;
                    298:        }
                    299:        name_list[i++] = "done";
                    300:        name_list[i] = 0;
                    301:        for (i = 0; i < num_play; i++)
1.19      dholland  302:                for (j = i + 1; j <= num_play; j++)
1.1       cgd       303:                        if (strcasecmp(name_list[i], name_list[j]) == 0) {
1.19      dholland  304:                                if (j != num_play)
1.6       simonb    305:                                        printf("Hey!!! Some of those are "
                    306:                                            "IDENTICAL!!  Let's try that "
1.19      dholland  307:                                            "again...\n");
1.1       cgd       308:                                else
1.6       simonb    309:                                        printf("\"done\" is a reserved word.  "
                    310:                                            "Please try again\n");
1.1       cgd       311:                                for (i = 0; i < num_play; i++)
1.4       christos  312:                                        free(play[i].name);
                    313:                                free(play);
1.1       cgd       314:                                goto blew_it;
                    315:                        }
                    316: }
1.6       simonb    317:
1.1       cgd       318: /*
                    319:  *     This routine figures out who goes first
                    320:  */
1.4       christos  321: static void
                    322: init_players()
                    323: {
1.6       simonb    324:        int i, rl, cur_max;
                    325:        bool over = 0;
                    326:        int max_pl = 0;
1.1       cgd       327:
                    328: again:
                    329:        putchar('\n');
                    330:        for (cur_max = i = 0; i < num_play; i++) {
                    331:                printf("%s (%d) rolls %d\n", play[i].name, i+1, rl=roll(2, 6));
                    332:                if (rl > cur_max) {
                    333:                        over = FALSE;
                    334:                        cur_max = rl;
                    335:                        max_pl = i;
                    336:                }
                    337:                else if (rl == cur_max)
                    338:                        over++;
                    339:        }
                    340:        if (over) {
                    341:                printf("%d people rolled the same thing, so we'll try again\n",
                    342:                    over + 1);
                    343:                goto again;
                    344:        }
                    345:        player = max_pl;
                    346:        cur_p = &play[max_pl];
                    347:        printf("%s (%d) goes first\n", cur_p->name, max_pl + 1);
                    348: }
1.6       simonb    349:
1.1       cgd       350: /*
1.12      wiz       351:  *     This routine initializes the monopoly structures.
1.1       cgd       352:  */
1.4       christos  353: static void
1.17      dholland  354: init_monops()
1.4       christos  355: {
1.6       simonb    356:        MON *mp;
                    357:        int i;
1.1       cgd       358:
                    359:        for (mp = mon; mp < &mon[N_MON]; mp++) {
                    360:                mp->name = mp->not_m;
                    361:                for (i = 0; i < mp->num_in; i++)
                    362:                        mp->sq[i] = &board[mp->sqnums[i]];
                    363:        }
                    364: }

CVSweb <webmaster@jp.NetBSD.org>