BSD 4_1_snap development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Thu, 11 Sep 1980 09:38:09 +0000 (01:38 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Thu, 11 Sep 1980 09:38:09 +0000 (01:38 -0800)
Work on file usr/src/games/monop/brd.dat
Work on file usr/src/games/monop/deck.h
Work on file usr/src/games/monop/getinp.c
Work on file usr/src/games/monop/jail.c
Work on file usr/src/games/monop/initdeck.c
Work on file usr/src/games/monop/mon.dat
Work on file usr/src/games/monop/monop.c
Work on file usr/src/games/monop/monop.def
Work on file usr/src/games/monop/monop.h
Work on file usr/src/games/monop/morg.c
Work on file usr/src/games/monop/print.c
Work on file usr/src/games/monop/prop.c
Work on file usr/src/games/monop/prop.dat
Work on file usr/src/games/monop/rent.c
Work on file usr/src/games/monop/strcmp.c
Work on file usr/src/games/monop/trade.c

Synthesized-from: CSRG/cd1/4.1.snap

16 files changed:
usr/src/games/monop/brd.dat [new file with mode: 0644]
usr/src/games/monop/deck.h [new file with mode: 0644]
usr/src/games/monop/getinp.c [new file with mode: 0644]
usr/src/games/monop/initdeck.c [new file with mode: 0644]
usr/src/games/monop/jail.c [new file with mode: 0644]
usr/src/games/monop/mon.dat [new file with mode: 0644]
usr/src/games/monop/monop.c [new file with mode: 0644]
usr/src/games/monop/monop.def [new file with mode: 0644]
usr/src/games/monop/monop.h [new file with mode: 0644]
usr/src/games/monop/morg.c [new file with mode: 0644]
usr/src/games/monop/print.c [new file with mode: 0644]
usr/src/games/monop/prop.c [new file with mode: 0644]
usr/src/games/monop/prop.dat [new file with mode: 0644]
usr/src/games/monop/rent.c [new file with mode: 0644]
usr/src/games/monop/strcmp.c [new file with mode: 0644]
usr/src/games/monop/trade.c [new file with mode: 0644]

diff --git a/usr/src/games/monop/brd.dat b/usr/src/games/monop/brd.dat
new file mode 100644 (file)
index 0000000..7af06d8
--- /dev/null
@@ -0,0 +1,43 @@
+/* name (COLOR)                        owner   type    desc            cost    */
+
+{"=== GO ===",                 -1,     SAFE,   0                       },
+{"Mediterranean ave. (P)",     -1,     PRPTY,  &prop[0],       60      },
+{"Community Chest i",          -1,     CC,     cc                      },
+{"Baltic ave. (P)",            -1,     PRPTY,  &prop[1],       60      },
+{"Income Tax",                 -1,     SPEC,   inc_tax                 },
+{"Reading RR",                 -1,     RR,     &rr[0],         200     },
+{"Oriental ave. (L)",          -1,     PRPTY,  &prop[2],       100     },
+{"Chance i",                   -1,     CHANCE, chance                  },
+{"Vermont ave. (L)",           -1,     PRPTY,  &prop[3],       100     },
+{"Connecticut ave. (L)",       -1,     PRPTY,  &prop[4],       120     },
+{"Just Visiting",              -1,     SAFE,   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     },
+{"Pennsylvania RR",            -1,     RR,     &rr[1],         200     },
+{"St. James pl. (O)",          -1,     PRPTY,  &prop[8],       180     },
+{"Community Chest ii",         -1,     CC,     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, chance                  },
+{"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     },
+{"Water Works",                        -1,     UTIL,   &util[1],       150     },
+{"Marvin Gardens (Y)",         -1,     PRPTY,  &prop[16],      280     },
+{"GO TO JAIL",                 -1,     SPEC,   goto_jail               },
+{"Pacific ave. (G)",           -1,     PRPTY,  &prop[17],      300     },
+{"N. Carolina ave. (G)",       -1,     PRPTY,  &prop[18],      300     },
+{"Community Chest iii",                -1,     CC,     cc                      },
+{"Pennsylvania ave. (G)",      -1,     PRPTY,  &prop[19],      320     },
+{"Short Line RR",              -1,     RR,     &rr[3],         200     },
+{"Chance iii",                 -1,     CHANCE, chance                  },
+{"Park place (D)",             -1,     PRPTY,  &prop[20],      350     },
+{"Luxury Tax",                 -1,     SPEC,   lux_tax                 },
+{"Boardwalk (D)",              -1,     PRPTY,  &prop[21],      400     },
+{"JAIL",                       -1,     SPEC                            }
diff --git a/usr/src/games/monop/deck.h b/usr/src/games/monop/deck.h
new file mode 100644 (file)
index 0000000..3363612
--- /dev/null
@@ -0,0 +1,13 @@
+# define       bool    char
+
+# define       CC_D    deck[0]
+# define       CH_D    deck[1]
+
+struct dk_st {                 /* deck description structure           */
+       int     num_cards;              /* number of cards in deck      */
+       int     last_card;              /* number of last card picked   */
+       bool    gojf_used;              /* set if gojf card out of deck */
+       long    *offsets;               /* offests for start of cards   */
+};
+
+typedef struct dk_st   DECK;
diff --git a/usr/src/games/monop/getinp.c b/usr/src/games/monop/getinp.c
new file mode 100644 (file)
index 0000000..838f589
--- /dev/null
@@ -0,0 +1,79 @@
+# include      <stdio.h>
+# include      <ctype.h>
+
+# define       reg     register
+
+# define       LINE    70
+
+static char    buf[257];
+
+getinp(prompt, list)
+char   *prompt, *list[]; {
+
+       reg int i, n_match, match;
+       char    *sp;
+       int     plen;
+
+
+       for (;;) {
+inter:
+               printf(prompt);
+               for (sp = buf; (*sp=getchar()) != '\n'; )
+                       if (*sp == -1)  /* check for interupted system call */
+                               goto inter;
+                       else if (sp != buf || *sp != ' ')
+                               sp++;
+               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) {
+                                       printf("\n\t");
+                                       match = n_match + 8;
+                               }
+                               if (*list[i] == '\0') {
+                                       match += 8;
+                                       printf("<RETURN>");
+                               }
+                               else
+                                       printf(list[i]);
+                               if (list[i+1])
+                                       printf(", ");
+                               else
+                                       putchar('\n');
+                               match += 2;
+                       }
+                       continue;
+               }
+               *sp = '\0';
+               for (sp = buf; *sp; sp++)
+                       if (isupper(*sp))
+                               *sp = tolower(*sp);
+               for (i = n_match = 0; list[i]; i++)
+                       if (comp(list[i])) {
+                               n_match++;
+                               match = i;
+                       }
+               if (n_match == 1)
+                       return match;
+               else if (buf[0] != '\0')
+                       printf("Illegal response: \"%s\".  Use '?' to get list of valid answers\n", buf);
+       }
+}
+
+static
+comp(s1)
+char   *s1; {
+
+       reg char        *sp, *tsp, c;
+
+       if (buf[0] != '\0')
+               for (sp = buf, tsp = s1; *sp; ) {
+                       c = isupper(*tsp) ? tolower(*tsp) : *tsp;
+                       tsp++;
+                       if (c != *sp++)
+                               return 0;
+               }
+       else if (*s1 != '\0')
+               return 0;
+       return 1;
+}
diff --git a/usr/src/games/monop/initdeck.c b/usr/src/games/monop/initdeck.c
new file mode 100644 (file)
index 0000000..d0c7a3c
--- /dev/null
@@ -0,0 +1,140 @@
+# include      <stdio.h>
+# include      "deck.h"
+
+/*
+ *     This program initializes the card files for monopoly.
+ * It reads in a data file with Com. Chest cards, followed by
+ * the Chance card.  The two are seperated by a line of "%-".
+ * All other cards are seperated by lines of "%%".  In the front
+ * of the file is the data for the decks in the same order.
+ * This includes the seek pointer for the start of each card.
+ * All cards start with their execution code, followed by the
+ * string to print, terminated with a null byte.
+ */
+
+# define       TRUE    1
+# define       FALSE   0
+
+# define       bool    char
+# define       reg     register
+
+char   *infile         = "cards.inp",          /* input file           */
+       *outfile        = "cards.pck";          /* "packed" file        */
+
+long   ftell();
+
+DECK   deck[2];
+
+FILE   *inf, *outf;
+
+main(ac, av)
+int    ac;
+char   *av[]; {
+
+       getargs(ac, av);
+       if ((inf = fopen(infile, "r")) == NULL) {
+               perror(infile);
+               exit(1);
+       }
+       count();
+       /*
+        * allocate space for pointers.
+        */
+       CC_D.offsets = calloc(CC_D.num_cards + 1, sizeof (long));
+       CH_D.offsets = calloc(CH_D.num_cards + 1, sizeof (long));
+       fseek(inf, 0L, 0);
+       if ((outf = fopen(outfile, "w")) == NULL) {
+               perror(outfile);
+               exit(0);
+       }
+
+       fwrite(deck, sizeof (DECK), 2, outf);
+       fwrite(CC_D.offsets, sizeof (long), CC_D.num_cards, outf);
+       fwrite(CH_D.offsets, sizeof (long), CH_D.num_cards, outf);
+       putem();
+
+       fclose(inf);
+       fseek(outf, 0, 0L);
+       fwrite(deck, sizeof (DECK), 2, outf);
+       fwrite(CC_D.offsets, sizeof (long), CC_D.num_cards, outf);
+       fwrite(CH_D.offsets, sizeof (long), CH_D.num_cards, outf);
+       fclose(outf);
+       printf("There were %d com. chest and %d chance cards\n", CC_D.num_cards, CH_D.num_cards);
+       exit(0);
+}
+
+getargs(ac, av)
+int    ac;
+char   *av[]; {
+
+       if (ac > 2) {
+               infile = av[2] ? av[2] : infile;
+               if (ac > 3)
+                       outfile = av[3];
+       }
+}
+/*
+ * count the cards
+ */
+count() {
+
+       reg bool        newline;
+       reg DECK        *in_deck;
+       reg char        c;
+
+       newline = TRUE;
+       in_deck = &CC_D;
+       while ((c=getc(inf)) != EOF)
+               if (newline && c == '%') {
+                       newline = FALSE;
+                       in_deck->num_cards++;
+                       if (getc(inf) == '-')
+                               in_deck = &CH_D;
+               }
+               else
+                       newline = (c == '\n');
+       in_deck->num_cards++;
+}
+/*
+ *     put strings in the file
+ */
+putem() {
+
+       reg bool        newline;
+       reg DECK        *in_deck;
+       reg char        c;
+       reg int         num;
+
+       in_deck = &CC_D;
+       CC_D.num_cards = 1;
+       CH_D.num_cards = 0;
+       CC_D.offsets[0] = ftell(outf);
+       putc(getc(inf), outf);
+       putc(getc(inf), outf);
+       for (num = 0; (c=getc(inf)) != '\n'; )
+               num = num * 10 + (c - '0');
+       putw(num, outf);
+       newline = FALSE;
+       while ((c=getc(inf)) != EOF)
+               if (newline && c == '%') {
+                       putc('\0', outf);
+                       newline = FALSE;
+                       if (getc(inf) == '-')
+                               in_deck = &CH_D;
+                       while (getc(inf) != '\n')
+                               continue;
+                       in_deck->offsets[in_deck->num_cards++] = ftell(outf);
+                       if ((c=getc(inf)) == EOF)
+                               break;
+                       putc(c, outf);
+                       putc(c = getc(inf), outf);
+                       for (num = 0; (c=getc(inf)) != EOF && c != '\n'; )
+                               num = num * 10 + (c - '0');
+                       putw(num, outf);
+               }
+               else {
+                       putc(c, outf);
+                       newline = (c == '\n');
+               }
+       putc('\0', outf);
+}
diff --git a/usr/src/games/monop/jail.c b/usr/src/games/monop/jail.c
new file mode 100644 (file)
index 0000000..c1309bc
--- /dev/null
@@ -0,0 +1,90 @@
+# include      "monop.ext"
+
+/*
+ *     This routine uses a get-out-of-jail-free card to get the
+ * player out of jail.
+ */
+card() {
+
+       if (cur_p->loc != JAIL) {
+               printf("But you're not IN Jail\n");
+               return;
+       }
+       if (cur_p->num_gojf == 0) {
+               printf("But you don't HAVE a get out of jail free card\n");
+               return;
+       }
+       ret_card(cur_p);
+       cur_p->loc = 10;                        /* just visiting        */
+       cur_p->in_jail = 0;
+}
+/*
+ *     This routine returns the players get-out-of-jail-free card
+ * to a deck.
+ */
+ret_card(plr)
+reg 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.
+ */
+pay() {
+
+       if (cur_p->loc != JAIL) {
+               printf("But you're not IN Jail\n");
+               return;
+       }
+       cur_p->loc = 10;
+       cur_p->money -= 50;
+       cur_p->in_jail = 0;
+       printf("That cost you $50\n");
+}
+/*
+ *     This routine deals with a move in jail
+ */
+move_jail(r1, r2)
+reg int        r1, r2; {
+
+       if (r1 != r2) {
+               printf("Sorry, that doesn't get you out\n");
+               if (++(cur_p->in_jail) == 3) {
+                       printf("It's your third turn and you didn't roll doubles.  You have to pay $50\n");
+                       cur_p->money -= 50;
+moveit:
+                       cur_p->loc = 10;
+                       cur_p->in_jail = 0;
+                       move(r1+r2);
+                       r1 = r2 - 1;    /* kludge: stop new roll w/doub */
+                       return TRUE;
+               }
+               return FALSE;
+       }
+       else {
+               printf("Double roll gets you out.\n");
+               goto moveit;
+       }
+}
+printturn() {
+
+       if (cur_p->loc != JAIL)
+               return;
+       printf("(This is your ");
+       switch (cur_p->in_jail) {
+         case 0:
+               printf("1st");
+               break;
+         case 1:
+               printf("2nd");
+               break;
+         case 2:
+               printf("3rd (and final)");
+               break;
+       }
+       printf(" turn in JAIL)\n");
+}
diff --git a/usr/src/games/monop/mon.dat b/usr/src/games/monop/mon.dat
new file mode 100644 (file)
index 0000000..cd49305
--- /dev/null
@@ -0,0 +1,9 @@
+/* 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}}
diff --git a/usr/src/games/monop/monop.c b/usr/src/games/monop/monop.c
new file mode 100644 (file)
index 0000000..5dea4aa
--- /dev/null
@@ -0,0 +1,119 @@
+# include      "monop.def"
+
+/*
+ *     This program implements a monopoly game
+ */
+main(ac, av)
+reg int                ac;
+reg char       *av[]; {
+
+
+       srand(getpid());
+       if (ac > 1) {
+               if (!rest_f(av[1]))
+                       restore();
+       }
+       else {
+               getplayers();
+               init_players();
+               init_monops();
+       }
+       num_luck = sizeof lucky_mes / sizeof (char *);
+       init_decks();
+       signal(2, quit);
+       for (;;) {
+               printf("\n%s (%d) (cash $%d) on %s\n", cur_p->name, player + 1,
+                       cur_p->money, board[cur_p->loc].name);
+               printturn();
+               force_morg();
+               execute(getinp("-- Command: ", comlist));
+       }
+}
+/*
+ *     This routine gets the names of the players
+ */
+getplayers() {
+
+       reg char        *sp;
+       reg int         i, j;
+       char            buf[257];
+
+blew_it:
+       for (;;) {
+               if ((num_play=get_int("How many players? ")) <= 0 ||
+                   num_play > MAX_PL)
+                       printf("Sorry. Number must range from 1 to 9\n");
+               else
+                       break;
+       }
+       cur_p = play = (PLAY *) calloc(num_play, sizeof (PLAY));
+       for (i = 0; i < num_play; i++) {
+over:
+               printf("Player %d's name: ", i + 1);
+               for (sp = buf; (*sp=getchar()) != '\n'; sp++)
+                       continue;
+               if (sp == buf)
+                       goto over;
+               *sp++ = '\0';
+               strcpy(name_list[i]=play[i].name=(char *)calloc(1,sp-buf),buf);
+               play[i].money = 1500;
+       }
+       name_list[i++] = "done";
+       name_list[i] = 0;
+       for (i = 0; i < num_play; i++)
+               for (j = i + 1; j < num_play; j++)
+                       if (strcmp(name_list[i], name_list[j]) == 0) {
+                               if (i != num_play - 1)
+                                       printf("Hey!!! Some of those are IDENTICAL!!  Let's try that again....\n");
+                               else
+                                       printf("\"done\" is a reserved word.  Please try again\n");
+                               for (i = 0; i < num_play; i++)
+                                       cfree(play[i].name);
+                               cfree(play);
+                               goto blew_it;
+                       }
+}
+/*
+ *     This routine figures out who goes first
+ */
+init_players() {
+
+       reg int i, rl, cur_max;
+       bool    over;
+       int     max_pl;
+
+again:
+       putchar('\n');
+       for (cur_max = i = 0; i < num_play; i++) {
+               printf("%s (%d) rolls %d\n", play[i].name, i+1, rl=roll(2, 6));
+               if (rl > cur_max) {
+                       over = FALSE;
+                       cur_max = rl;
+                       max_pl = i;
+               }
+               else if (rl == cur_max)
+                       over++;
+       }
+       if (over) {
+               printf("%d people rolled the same thing, so we'll try again\n",
+                   over + 1);
+               goto again;
+       }
+       player = max_pl;
+       cur_p = &play[max_pl];
+       printf("%s (%d) goes first\n", cur_p->name, max_pl + 1);
+}
+/*
+ *     This routine initalizes the monopoly structures.
+ */
+init_monops() {
+
+       reg MON *mp;
+       reg int i;
+
+       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[(int)(mp->sq[i])];
+       }
+}
diff --git a/usr/src/games/monop/monop.def b/usr/src/games/monop/monop.def
new file mode 100644 (file)
index 0000000..d7acbe2
--- /dev/null
@@ -0,0 +1,89 @@
+# include      "monop.h"
+# include      "deck.h"
+
+bool   fixing,                 /* set if fixing up debt                */
+       trading,                /* 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  */
+
+char   *name_list[MAX_PL+2],   /* list of players' names               */
+       *comlist[]      = {     /* list of normal commands              */
+       "quit",         /*  0 */        "print",        /*  1 */
+       "where",        /*  2 */        "own holdings", /*  3 */
+       "holdings",     /*  4 */        "shell",        /*  5 */
+       "mortgage",     /*  6 */        "unmortgage",   /*  7 */
+       "buy houses",   /*  8 */        "sell houses",  /*  9 */
+       "card",         /* 10 */        "pay",          /* 11 */
+       "trade",        /* 12 */        "resign",       /* 13 */
+       "save",         /* 14 */        "restore",      /* 15 */
+       "roll",         /* 16 */        "",             /* 17 */
+       0
+       },
+       *yn[]           = {     /* list of commands for yes/no answers  */
+       "yes",          /*  0 */        "no",           /*  1 */
+       "quit",         /*  2 */        "print",        /*  3 */
+       "where",        /*  4 */        "own holdings", /*  5 */
+       "holdings",     /*  6 */        "shell",        /*  7 */
+       0
+       },
+       *lucky_mes[]    = {     /* "got lucky" messages                 */
+       "You lucky stiff",              "You got lucky",
+       "What a lucky person!",         "You must have a 4-leaf clover",
+       "My, my!  Aren't we lucky!",    "Luck smiles upon you",
+       "You got lucky this time",      "Lucky person!",
+       "Your karma must certainly be together",
+       "How beautifully Cosmic",       "Wow, you must be really with it"
+       /* "I want your autograph",     -- Save for later */
+       };
+
+int    player,                 /* current player number                */
+       num_play,               /* current number of players            */
+       num_doub,               /* # of doubles current player rolled   */
+                               /* # of "got lucky" messages            */
+       num_luck        = sizeof lucky_mes / sizeof (char *),
+                               /* list of command functions            */
+       buy_houses(), card(), do_move(), do_move(), list(), list_all(),
+       mortgage(), pay(), printboard(), quit(), resign(), restore(),
+       rub(), save(), sell_houses(), shell_out(), trade(),
+       unmortgage(), where(),
+       (*func[])()     = {     /* array of function calls for commands */
+       quit,                   /* quit game            |*  0 *|        */
+       printboard,             /* print board          |*  1 *|        */
+       where,                  /* where players are    |*  2 *|        */
+       list,                   /* own holdings         |*  3 *|        */
+       list_all,               /* holdings list        |*  4 *|        */
+       shell_out,              /* shell                |*  5 *|        */
+       mortgage,               /* mortgage property    |*  6 *|        */
+       unmortgage,             /* unmortgage property  |*  7 *|        */
+       buy_houses,             /* buy houses           |*  8 *|        */
+       sell_houses,            /* sell houses          |*  9 *|        */
+       card,                   /* card for jail        |* 10 *|        */
+       pay,                    /* pay for jail         |* 11 *|        */
+       trade,                  /* trade                |* 12 *|        */
+       resign,                 /* resign               |* 13 *|        */
+       save,                   /* save game            |* 14 *|        */
+       restore,                /* restore game         |* 15 *|        */
+       do_move,                /* roll                 |* 16 *|        */
+       do_move                 /* ""                   |* 17 *|        */
+       };
+
+DECK   deck[2];                /* Chance and Community Chest           */
+
+PLAY   *play,                  /* player structure array ("calloc"ed)  */
+       *cur_p;                 /* pointer to current player's struct   */
+
+RR_S   rr[N_RR];               /* raildroad descriptions               */
+
+UTIL_S util[2];                /* utility descriptions                 */
+
+MON    mon[N_MON]      = {     /* monopoly descriptions                */
+#              include "mon.dat"
+};
+
+PROP   prop[N_PROP]    = {     /* typical properties                   */
+#              include "prop.dat"
+};
+
+SQUARE board[N_SQRS+1] = {     /* board itself (+1 for Jail)           */
+#              include "brd.dat"
+};
diff --git a/usr/src/games/monop/monop.h b/usr/src/games/monop/monop.h
new file mode 100644 (file)
index 0000000..0e53371
--- /dev/null
@@ -0,0 +1,98 @@
+# include      <stdio.h>
+
+# define       reg     register
+# define       shrt    char
+# define       bool    char
+# define       unsgn   unsigned
+
+# define       TRUE    (1)
+# define       FALSE   (0)
+
+# define       N_MON   8       /* number of monopolies                 */
+# define       N_PROP  22      /* number of normal property squares    */
+# define       N_RR    4       /* number of railroads                  */
+# define       N_UTIL  2       /* number of utilities                  */
+# 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  */
+
+                               /* square type numbers                  */
+# define       PRPTY   0       /* normal property                      */
+# define       RR      1       /* railroad                             */
+# define       UTIL    2       /* water works - electric co            */
+# define       SAFE    3       /* safe spot                            */
+# define       CC      4       /* community chest                      */
+# define       CHANCE  5       /* chance (surprise!!!)                 */
+# define       SPEC    6       /* special                              */
+
+# define       JAIL    40      /* JAIL square number                   */
+
+# define       lucky(str)      printf("%s%s\n",str,lucky_mes[roll(1,num_luck)-1])
+# define       printline()     printf("------------------------------\n")
+# define       sqnum(sqp)      (sqp - board)
+# define       swap(A1,A2)     if ((A1) != (A2)) { \
+                                       (A1) ^= (A2); \
+                                       (A2) ^= (A1); \
+                                       (A1) ^= (A2); \
+                               }
+
+struct sqr_st {                        /* structure for square                 */
+       char    *name;                  /* place name                   */
+       shrt    owner;                  /* owner number                 */
+       shrt    type;                   /* place type                   */
+       char    *desc;                  /* description struct           */
+       int     cost;                   /* cost                         */
+};
+
+typedef struct sqr_st  SQUARE;
+
+struct mon_st {                        /* monopoly descriptin structure        */
+       char    *name;                  /* monop. name (color)          */
+       shrt    owner;                  /* owner of monopoly            */
+       shrt    num_in;                 /* # in monopoly                */
+       shrt    num_own;                /* # owned (-1: not poss. monop)*/
+       shrt    h_cost;                 /* price of houses              */
+       char    *not_m;                 /* name if not monopoly         */
+       char    *mon_n;                 /* name if a monopoly           */
+       SQUARE  *sq[3];                 /* list of squares in monop     */
+};
+
+typedef struct mon_st  MON;
+
+struct prp_st {                        /* property description structure       */
+       bool    morg;                   /* set if mortgaged             */
+       bool    monop;                  /* set if monopoly              */
+       shrt    square;                 /* square description           */
+       shrt    houses;                 /* number of houses             */
+       MON     *mon_desc;              /* name of color                */
+       int     rent[6];                /* rents                        */
+};
+
+struct own_st {                        /* element in list owned things         */
+       SQUARE  *sqr;                   /* pointer to square            */
+       struct own_st   *next;          /* next in list                 */
+};
+
+typedef struct own_st  OWN;
+
+struct plr_st {                        /* player description structure         */
+       char    *name;                  /* owner name                   */
+       shrt    num_gojf;               /* # of get-out-of-jail-free's  */
+       shrt    num_rr;                 /* # of railroads owned         */
+       shrt    num_util;               /* # of water works/elec. co.   */
+       shrt    loc;                    /* location on board            */
+       shrt    in_jail;                /* count of turns in jail       */
+       int     money;                  /* amount of money              */
+       OWN     *own_list;              /* start of propery list        */
+};
+
+struct rr_st {                 /* railroad description structure       */
+       bool    morg;                   /* set if morgaged              */
+};
+
+typedef struct plr_st  PLAY;
+typedef struct prp_st  PROP;
+typedef struct rr_st   RR_S;
+typedef struct rr_st   UTIL_S;
+
+int    cc(), chance(), lux_tax(), goto_jail(), inc_tax();
diff --git a/usr/src/games/monop/morg.c b/usr/src/games/monop/morg.c
new file mode 100644 (file)
index 0000000..6a07347
--- /dev/null
@@ -0,0 +1,173 @@
+# include      "monop.ext"
+
+/*
+ *     These routines deal with mortgaging.
+ */
+
+static char    *names[MAX_PRP+2],
+               *morg_coms[]    = {
+                       "quit",         /*  0 */
+                       "print",        /*  1 */
+                       "where",        /*  2 */
+                       "own holdings", /*  3 */
+                       "holdings",     /*  4 */
+                       "shell",        /*  5 */
+                       "mortgage",     /*  6 */
+                       "unmortgage",   /*  7 */
+                       "buy",          /*  8 */
+                       "sell",         /*  9 */
+                       "card",         /* 10 */
+                       "pay",          /* 11 */
+                       "trade",        /* 12 */
+                       "resign",       /* 13 */
+                       "save game",    /* 14 */
+                       "restore game", /* 15 */
+                       0
+               };
+
+static shrt    square[MAX_PRP+2];
+
+static int     num_good,got_houses;
+
+/*
+ *     This routine is the command level response the mortgage command.
+ * it gets the list of mortgageable property and asks which are to
+ * be mortgaged.
+ */
+mortgage() {
+
+       reg int prop;
+
+       for (;;) {
+               if (set_mlist() == 0) {
+                       if (got_houses)
+                               printf("You can't mortgage property with houses on it.\n");
+                       else
+                               printf("You don't have any un-mortgaged property.\n");
+                       return;
+               }
+               if (num_good == 1) {
+                       printf("Your only mortageable property is %s\n",names[0]);
+                       if (getyn("Do you want to mortgage it? ") == 0)
+                               m(square[0]);
+                       return;
+               }
+               prop = getinp("Which property do you want to mortgage? ",names);
+               if (prop == num_good)
+                       return;
+               m(square[prop]);
+               notify(cur_p);
+       }
+}
+/*
+ *     This routine sets up the list of mortgageable property
+ */
+set_mlist() {
+
+       reg OWN *op;
+
+       num_good = 0;
+       for (op = cur_p->own_list; op; op = op->next)
+               if (!op->sqr->desc->morg)
+                       if (op->sqr->type == PRPTY && op->sqr->desc->houses)
+                               got_houses++;
+                       else {
+                               names[num_good] = op->sqr->name;
+                               square[num_good++] = sqnum(op->sqr);
+                       }
+       names[num_good++] = "done";
+       names[num_good--] = 0;
+       return num_good;
+}
+/*
+ *     This routine actually mortgages the property.
+ */
+m(prop)
+reg int        prop; {
+
+       reg int price;
+
+       price = board[prop].cost/2;
+       board[prop].desc->morg = TRUE;
+       printf("That got you $%d\n",price);
+       cur_p->money += price;
+}
+/*
+ *     This routine is the command level repsponse to the unmortgage
+ * command.  It gets the list of mortgaged property and asks which are
+ * to be unmortgaged.
+ */
+unmortgage() {
+
+       reg int prop;
+
+       for (;;) {
+               if (set_umlist() == 0) {
+                       printf("You don't have any mortgaged property.\n");
+                       return;
+               }
+               if (num_good == 1) {
+                       printf("Your only mortaged property is %s\n",names[0]);
+                       if (getyn("Do you want to unmortgage it? ") == 0)
+                               unm(square[0]);
+                       return;
+               }
+               prop = getinp("Which property do you want to unmortgage? ",names);
+               if (prop == num_good)
+                       return;
+               unm(square[prop]);
+       }
+}
+/*
+ *     This routine sets up the list of mortgaged property
+ */
+set_umlist() {
+
+       reg OWN *op;
+
+       num_good = 0;
+       for (op = cur_p->own_list; op; op = op->next)
+               if (op->sqr->desc->morg) {
+                       names[num_good] = op->sqr->name;
+                       square[num_good++] = sqnum(op->sqr);
+               }
+       names[num_good++] = "done";
+       names[num_good--] = 0;
+       return num_good;
+}
+/*
+ *     This routine actually unmortgages the property
+ */
+unm(prop)
+reg int        prop; {
+
+       reg int price;
+
+       price = board[prop].cost/2;
+       board[prop].desc->morg = FALSE;
+       price += price/10;
+       printf("That cost you $%d\n",price);
+       cur_p->money -= price;
+       set_umlist();
+}
+/*
+ *     This routine forces the indebted player to fix his
+ * financial woes.
+ */
+force_morg() {
+
+       told_em = fixing = TRUE;
+       while (cur_p->money <= 0)
+               fix_ex(getinp("How are you going to fix it up? ",morg_coms));
+       fixing = FALSE;
+}
+/*
+ *     This routine is a special execute for the force_morg routine
+ */
+fix_ex(com_num)
+reg int        com_num; {
+
+       told_em = FALSE;
+       (*func[com_num])();
+       notify();
+}
diff --git a/usr/src/games/monop/print.c b/usr/src/games/monop/print.c
new file mode 100644 (file)
index 0000000..d7e27b6
--- /dev/null
@@ -0,0 +1,154 @@
+# include      "monop.ext"
+
+static char    buf[80],                /* output buffer                */
+               *header = "Name      Own      Price Mg # Rent";
+
+/*
+ *     This routine prints out the current board
+ */
+printboard() {
+
+       reg int i;
+
+       printf("%s\t%s\n", header, header);
+       for (i = 0; i < N_SQRS/2; i++) {
+               printsq(i, FALSE);
+               putchar('\t');
+               printsq(i+N_SQRS/2, TRUE);
+       }
+}
+/*
+ *     This routine lists where each player is.
+ */
+where() {
+
+       reg int i;
+       char    *bsp;
+
+       printf("%s Player\n", header);
+       for (i = 0; i < num_play; i++) {
+               printsq(play[i].loc, FALSE);
+               printf(" %s (%d)", play[i].name, i+1);
+               if (cur_p == &play[i])
+                       printf(" *");
+               putchar('\n');
+       }
+}
+/*
+ *     This routine prints out an individual square
+ */
+printsq(sqn, eoln)
+int            sqn;
+reg bool       eoln; {
+
+       reg int         rnt;
+       reg PROP        *pp;
+       reg SQUARE      *sqp;
+       int             i;
+
+       sqp = &board[sqn];
+       printf("%-10.10s", sqp->name);
+       if (sqn == JAIL)
+               goto spec;
+       switch (sqp->type) {
+         case SAFE:
+         case CC:
+         case CHANCE:
+         case SPEC:
+spec:
+               if (!eoln)
+                       printf("                        ");
+               break;
+         case PRPTY:
+               pp = sqp->desc;
+               if (sqp->owner < 0) {
+                       printf(" - %-8.8s %3d", pp->mon_desc->name, sqp->cost);
+                       if (!eoln)
+                               printf("         ");
+                       break;
+               }
+               printf(" %d %-8.8s %3d", sqp->owner+1, pp->mon_desc->name,
+                       sqp->cost);
+               printmorg(sqp);
+               if (pp->monop) {
+                       if (pp->houses < 5)
+                               if (pp->houses > 0)
+                                       printf("%d %4d", pp->houses,
+                                               pp->rent[pp->houses]);
+                               else
+                                       printf("0 %4d", pp->rent[0] * 2);
+                       else
+                               printf("H %4d", pp->rent[5]);
+               }
+               else
+                       printf("  %4d", pp->rent[0]);
+               break;
+         case UTIL:
+               if (sqp->owner < 0) {
+                       printf(" -          150");
+                       if (!eoln)
+                               printf("         ");
+                       break;
+               }
+               printf(" %d          150", sqp->owner+1);
+               printmorg(sqp);
+               printf("%d", play[sqp->owner].num_util);
+               if (!eoln)
+                       printf("    ");
+               break;
+         case RR:
+               if (sqp->owner < 0) {
+                       printf(" - Railroad 200");
+                       if (!eoln)
+                               printf("         ");
+                       break;
+               }
+               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));
+               break;
+       }
+       if (eoln)
+               putchar('\n');
+}
+/*
+ *     This routine prints out the mortgage flag.
+ */
+printmorg(sqp)
+reg SQUARE     *sqp; {
+
+       if (sqp->desc->morg)
+               printf(" * ");
+       else
+               printf("   ");
+}
+/*
+ *     This routine lists the holdings of the player given
+ */
+printhold(pl)
+reg int        pl; {
+
+       reg OWN         *op;
+       reg PLAY        *pp;
+       char            *bsp;
+
+       pp = &play[pl];
+       printf("%s's (%d) holdings (Total worth: $%d):\n", name_list[pl], pl+1,
+               pp->money + prop_worth(pp));
+       printf("\t$%d", pp->money);
+       if (pp->num_gojf) {
+               printf(", %d get-out-of-jail-free card", pp->num_gojf);
+               if (pp->num_gojf > 1)
+                       putchar('s');
+       }
+       putchar('\n');
+       if (pp->own_list) {
+               printf("\t%s\n", header);
+               for (op = pp->own_list; op; op = op->next) {
+                       putchar('\t');
+                       printsq(sqnum(op->sqr), TRUE);
+               }
+       }
+}
diff --git a/usr/src/games/monop/prop.c b/usr/src/games/monop/prop.c
new file mode 100644 (file)
index 0000000..846f2ff
--- /dev/null
@@ -0,0 +1,172 @@
+# include      "monop.ext"
+
+/*
+ *     This routine deals with buying property, setting all the
+ * appropriate flags.
+ */
+buy(player, sqrp)
+reg int                player;
+reg SQUARE     *sqrp; {
+
+       trading = FALSE;
+       sqrp->owner = player;
+       add_list(player, &(play[player].own_list), cur_p->loc);
+}
+/*
+ *     This routine adds an item to the list.
+ */
+add_list(plr, head, op_sqr)
+int    plr;
+OWN    **head;
+int    op_sqr; {
+
+       reg int val;
+       reg OWN *tp, *last_tp;
+       MON     *mp;
+       OWN     *op;
+
+       op = calloc(1, sizeof (OWN));
+       op->sqr = &board[op_sqr];
+       val = value(op->sqr);
+       last_tp = NULL;
+       for (tp = *head; tp && value(tp->sqr) < val; tp = tp->next)
+               if (val == value(tp->sqr)) {
+                       cfree(op);
+                       return;
+               }
+               else
+                       last_tp = tp;
+       op->next = tp;
+       if (last_tp != NULL)
+               last_tp->next = op;
+       else
+               *head = op;
+       if (!trading)
+               set_ownlist(plr);
+}
+/*
+ *     This routine deletes property from the list.
+ */
+del_list(plr, head, op_sqr)
+int    plr;
+OWN    **head;
+shrt   op_sqr; {
+
+       reg int i;
+       reg OWN *op, *last_op;
+
+       switch (board[op_sqr].type) {
+         case PRPTY:
+               board[op_sqr].desc->mon_desc->num_own--;
+               break;
+         case RR:
+               play[plr].num_rr--;
+               break;
+         case UTIL:
+               play[plr].num_util--;
+               break;
+       }
+       last_op = NULL;
+       for (op = *head; op; op = op->next)
+               if (op->sqr == &board[op_sqr])
+                       break;
+               else
+                       last_op = op;
+       if (last_op == NULL)
+               *head = op->next;
+       else {
+               last_op->next = op->next;
+               cfree(op);
+       }
+}
+/*
+ *     This routine calculates the value for sorting of the
+ * given square.
+ */
+value(sqp)
+reg SQUARE     *sqp; {
+
+       reg int sqr;
+
+       sqr = sqnum(sqp);
+       switch (sqp->type) {
+         case SAFE:
+               return 0;
+         case SPEC:
+               return 1;
+         case UTIL:
+               if (sqr == 12)
+                       return 2;
+               else
+                       return 3;
+         case RR:
+               return 4 + sqr/10;
+         case PRPTY:
+               return 8 + (PROP *)(sqp->desc) - prop;
+       }
+}
+/*
+ *     This routine accepts bids for the current peice
+ * of property.
+ */
+bid() {
+
+       static bool     in[MAX_PL];
+       reg int         i, num_in, cur_max;
+       char            buf[80];
+       int             cur_bid;
+
+       printf("\nSo it goes up for auction.  Type your bid after your name\n");
+       for (i = 0; i < num_play; i++)
+               in[i] = TRUE;
+       i = -1;
+       cur_max = 0;
+       num_in = num_play;
+       while (num_in > 1 || (cur_max == 0 && num_in > 0)) {
+               i = ++i % num_play;
+               if (in[i]) {
+                       do {
+                               sprintf(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) {
+                                       printf("You must bid higher than %d to stay in\n", cur_max);
+                                       printf("(bid of 0 drops you out)\n");
+                               }
+                       } while (cur_bid != 0 && cur_bid <= cur_max);
+                       cur_max = (cur_bid ? cur_bid : cur_max);
+               }
+       }
+       if (cur_max != 0) {
+               while (!in[i])
+                       i = ++i % num_play;
+               printf("It goes to %s (%d) for $%d\n",play[i].name,i+1,cur_max);
+               buy(i, &board[cur_p->loc]);
+               play[i].money -= cur_max;
+       }
+       else
+               printf("Nobody seems to want it, so we'll leave it for later\n");
+}
+/*
+ *     This routine calculates the value of the property
+ * of given player.
+ */
+prop_worth(plp)
+reg PLAY       *plp; {
+
+       reg OWN *op;
+       reg int worth;
+
+       worth = 0;
+       for (op = plp->own_list; op; op = op->next) {
+               if (op->sqr->type == PRPTY && op->sqr->desc->monop)
+                       worth += op->sqr->desc->mon_desc->h_cost * 50 *
+                           op->sqr->desc->houses;
+               worth += op->sqr->cost;
+       }
+       return worth;
+}
diff --git a/usr/src/games/monop/prop.dat b/usr/src/games/monop/prop.dat
new file mode 100644 (file)
index 0000000..c947b39
--- /dev/null
@@ -0,0 +1,23 @@
+/* morg        monop   square  houses  mon_desc        rent    */
+{0,    0,      1,      0,      &mon[0],        { 2, 10, 30,  90, 160, 250} },
+{0,    0,      3,      0,      &mon[0],        { 4, 20, 60, 180, 320, 450} },
+{0,    0,      6,      0,      &mon[1],        { 6, 30, 90, 270, 400, 550} },
+{0,    0,      7,      0,      &mon[1],        { 6, 30, 90, 270, 400, 550} },
+{0,    0,      9,      0,      &mon[1],        { 8, 40,100, 300, 450, 600} },
+{0,    0,      11,     0,      &mon[2],        {10, 50,150, 450, 625, 750} },
+{0,    0,      13,     0,      &mon[2],        {10, 50,150, 450, 625, 750} },
+{0,    0,      14,     0,      &mon[2],        {12, 60,180, 500, 700, 900} },
+{0,    0,      16,     0,      &mon[3],        {14, 70,200, 550, 750, 950} },
+{0,    0,      17,     0,      &mon[3],        {14, 70,200, 550, 750, 950} },
+{0,    0,      19,     0,      &mon[3],        {16, 80,220, 600, 800,1000} },
+{0,    0,      21,     0,      &mon[4],        {18, 90,250, 700, 875,1050} },
+{0,    0,      23,     0,      &mon[4],        {18, 90,250, 700, 875,1050} },
+{0,    0,      24,     0,      &mon[4],        {20,100,300, 750, 925,1100} },
+{0,    0,      26,     0,      &mon[5],        {22,110,330, 800, 975,1150} },
+{0,    0,      27,     0,      &mon[5],        {22,110,330, 800, 975,1150} },
+{0,    0,      29,     0,      &mon[5],        {24,120,360, 850,1025,1200} },
+{0,    0,      31,     0,      &mon[6],        {26,130,390, 900,1100,1275} },
+{0,    0,      32,     0,      &mon[6],        {26,130,390, 900,1100,1275} },
+{0,    0,      34,     0,      &mon[6],        {28,150,450,1000,1200,1400} },
+{0,    0,      37,     0,      &mon[7],        {35,175,500,1100,1300,1500} },
+{0,    0,      39,     0,      &mon[7],        {50,200,600,1400,1700,2000} }
diff --git a/usr/src/games/monop/rent.c b/usr/src/games/monop/rent.c
new file mode 100644 (file)
index 0000000..7357f8f
--- /dev/null
@@ -0,0 +1,55 @@
+# include      "monop.ext"
+
+/*
+ *     This routine has the player pay rent
+ */
+rent(sqp)
+reg SQUARE     *sqp; {
+
+       reg int         rnt;
+       reg PROP        *pp;
+       PLAY            *plp;
+
+       plp = &play[sqp->owner];
+       printf("Owned by %s\n", plp->name);
+       if (sqp->desc->morg) {
+               lucky("The thing is mortgaged.  ");
+               return;
+       }
+       switch (sqp->type) {
+         case PRPTY:
+               pp = sqp->desc;
+               if (pp->monop)
+                       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]);
+                       else
+                               printf("with a hotel, rent is %d\n",
+                                   rnt=pp->rent[pp->houses]);
+               else
+                       printf("rent is %d\n", rnt = pp->rent[0]);
+               break;
+         case RR:
+               rnt = 25;
+               rnt <<= (plp->num_rr - 1);
+               if (spec)
+                       rnt <<= 1;
+               printf("rent is %d\n", rnt);
+               break;
+         case UTIL:
+               rnt = roll(2, 6);
+               if (plp->num_util == 2 || spec) {
+                       printf("rent is 10 * roll (%d) = %d\n", rnt, rnt * 10);
+                       rnt *= 10;
+               }
+               else {
+                       printf("rent is 4 * roll (%d) = %d\n", rnt, rnt * 4);
+                       rnt *= 4;
+               }
+               break;
+       }
+       cur_p->money -= rnt;
+       plp->money += rnt;
+}
diff --git a/usr/src/games/monop/strcmp.c b/usr/src/games/monop/strcmp.c
new file mode 100644 (file)
index 0000000..1c53627
--- /dev/null
@@ -0,0 +1,21 @@
+# include      <stdio.h>
+# include      <ctype.h>
+
+# define       reg     register
+
+# define       makelower(c)    (isupper(c) ? tolower(c) : c)
+
+/*
+ * Compare strings:  s1>s2: >0  s1==s2: 0  s1<s2: <0
+ */
+
+strcmp(s1, s2)
+reg char       *s1, *s2; {
+
+       while (makelower(*s1) == makelower(*s2)) {
+               if (*s1 == '\0')
+                       return 0;
+               s1++, s2++;
+       }
+       return *s1 - *s2;
+}
diff --git a/usr/src/games/monop/trade.c b/usr/src/games/monop/trade.c
new file mode 100644 (file)
index 0000000..70e8c5a
--- /dev/null
@@ -0,0 +1,271 @@
+# include      "monop.ext"
+
+static struct  trd_st {        /* how much to give to other player     */
+       int     trader;                 /* trader number                */
+       int     cash;                   /* amount of cash               */
+       int     gojf;                   /* # get-out-of-jail-free cards */
+       OWN     *prop_list;             /* property list                */
+};
+
+typedef        struct trd_st   TRADE;
+
+static char    *list[MAX_PRP+2];
+
+static int     used[MAX_PRP];
+
+static TRADE   trades[2];
+
+trade() {
+
+       reg int tradee, i;
+
+       trading = TRUE;
+       for (i = 0; i < 2; i++) {
+               trades[i].cash = 0;
+               trades[i].gojf = FALSE;
+               trades[i].prop_list = NULL;
+       }
+over:
+       if (num_play == 1) {
+               printf("There ain't no-one around to trade WITH!!\n");
+               return;
+       }
+       if (num_play > 2) {
+               tradee = getinp("Which player do you wish to trade with? ",
+                   name_list);
+               if (tradee == num_play)
+                       return;
+               if (tradee == player) {
+                       printf("You can't trade with yourself!\n");
+                       goto over;
+               }
+       }
+       else
+               tradee = 1 - player;
+       get_list(0, player);
+       get_list(1, tradee);
+       if (getyn("Do you wish a summary? ") == 0)
+               summate();
+       if (getyn("Is the trade ok? ") == 0)
+               do_trade();
+}
+/*
+ *     This routine gets the list of things to be trader for the
+ * player, and puts in the structure given.
+ */
+get_list(struct_no, play_no)
+int    struct_no, play_no; {
+
+       reg int         sn, pn;
+       reg PLAY        *pp;
+       int             numin, prop, num_prp;
+       OWN             *op;
+       TRADE           *tp;
+
+       for (numin = 0; numin < MAX_PRP; numin++)
+               used[numin] = FALSE;
+       sn = struct_no, pn = play_no;
+       pp = &play[pn];
+       tp = &trades[sn];
+       tp->trader = pn;
+       printf("player %s (%d):\n", pp->name, pn+1);
+       if (pp->own_list) {
+               numin = set_list(pp->own_list);
+               for (num_prp = numin; num_prp; ) {
+                       prop = getinp("Which property do you wish to trade? ",
+                           list);
+                       if (prop == numin)
+                               break;
+                       else if (used[prop])
+                               printf("You've already allocated that.\n");
+                       else {
+                               num_prp--;
+                               used[prop] = TRUE;
+                               for (op = pp->own_list; prop--; op = op->next)
+                                       continue;
+                               add_list(pn, &(tp->prop_list), sqnum(op->sqr));
+                       }
+               }
+       }
+       if (pp->money > 0) {
+               printf("You have $%d.  ", pp->money);
+               tp->cash = get_int("How much are you trading? ");
+       }
+       if (pp->num_gojf > 0) {
+once_more:
+               printf("You have %d get-out-of-jail-free cards. ",pp->num_gojf);
+               tp->gojf = get_int("How many are you trading? ");
+               if (tp->gojf > pp->num_gojf) {
+                       printf("You don't have that many.  Try again.\n");
+                       goto once_more;
+               }
+       }
+}
+/*
+ *     This routine sets up the list of tradable property.
+ */
+set_list(the_list)
+reg OWN        *the_list; {
+
+       reg int i;
+       reg OWN *op;
+
+       i = 0;
+       for (op = the_list; op; op = op->next)
+               if (!used[i])
+                       list[i++] = op->sqr->name;
+       list[i++] = "done";
+       list[i--] = 0;
+       return i;
+}
+/*
+ *     This routine summates the trade.
+ */
+summate() {
+
+       reg bool        some;
+       reg int         i;
+       reg TRADE       *tp;
+       OWN     *op;
+
+       for (i = 0; i < 2; i++) {
+               tp = &trades[i];
+               some = FALSE;
+               printf("Player %s (%d) gives:\n", play[tp->trader].name,
+                       tp->trader+1);
+               if (tp->cash > 0)
+                       printf("\t$%d\n", tp->cash), some++;
+               if (tp->gojf > 0)
+                       printf("\t%d get-out-of-jail-free card(s)\n", tp->gojf),
+                       some++;
+               if (tp->prop_list) {
+                       for (op = tp->prop_list; op; op = op->next)
+                               putchar('\t'), printsq(sqnum(op->sqr), TRUE);
+                       some++;
+               }
+               if (!some)
+                       printf("\t-- Nothing --\n");
+       }
+}
+/*
+ *     This routine actually executes the trade.
+ */
+do_trade() {
+
+       move_em(&trades[0], &trades[1]);
+       move_em(&trades[1], &trades[0]);
+}
+/*
+ *     This routine does a switch from one player to another
+ */
+move_em(from, to)
+TRADE  *from, *to; {
+
+       reg PLAY        *pl_fr, *pl_to;
+       reg OWN         *op;
+
+       pl_fr = &play[from->trader];
+       pl_to = &play[to->trader];
+
+       pl_fr->money -= from->cash;
+       pl_to->money += from->cash;
+       pl_fr->num_gojf -= from->gojf;
+       pl_to->num_gojf += from->gojf;
+       for (op = from->prop_list; op; op = op->next) {
+               add_list(to->trader, &(pl_to->own_list), sqnum(op->sqr));
+               op->sqr->owner = to->trader;
+               del_list(from->trader, &(pl_fr->own_list), sqnum(op->sqr));
+       }
+       set_ownlist(to->trader);
+}
+/*
+ *     This routine lets a player resign
+ */
+resign() {
+
+       reg int i, new_own;
+       reg OWN *op;
+       SQUARE  *sqp;
+
+       if (cur_p->money <= 0) {
+               switch (board[cur_p->loc].type) {
+                 case UTIL:
+                 case RR:
+                 case PRPTY:
+                       new_own = board[cur_p->loc].owner;
+                       break;
+                 case SPEC:
+                 case CC:
+                 case CHANCE:
+                       new_own = num_play;
+                       break;
+               }
+               if (new_own == num_play)
+                       printf("You would resign to the bank\n");
+               else
+                       printf("You would resign to %s\n", name_list[new_own]);
+       }
+       else if (num_play == 1) {
+               new_own = num_play;
+               printf("You would resign to the bank\n");
+       }
+       else {
+               name_list[num_play] = "bank";
+               do {
+                       new_own = getinp("Who do you wish to resign to? ",
+                           name_list);
+                       if (new_own == player)
+                               printf("You can't resign to yourself!!\n");
+               } while (new_own == player);
+               name_list[num_play] = "done";
+       }
+       if (getyn("Do you really want to resign? ", yn) != 0)
+               return;
+       if (num_play == 1) {
+               printf("Then NOBODY wins (not even YOU!)\n");
+               exit(0);
+       }
+       if (new_own < num_play) {       /* resign to player             */
+               printf("resigning to player\n");
+               trades[0].trader = new_own;
+               trades[0].cash = trades[0].gojf = 0;
+               trades[0].prop_list = NULL;
+               trades[1].trader = player;
+               trades[1].cash = cur_p->money > 0 ? cur_p->money : 0;
+               trades[1].gojf = cur_p->num_gojf;
+               trades[1].prop_list = cur_p->own_list;
+               do_trade();
+       }
+       else {                          /* resign to bank               */
+               printf("resigning to bank\n");
+               for (op = cur_p->own_list; op; op = op->next) {
+                       sqp = op->sqr;
+                       sqp->owner = -1;
+                       sqp->desc->morg = FALSE;
+                       if (op->type == PRPTY) {
+                               isnot_monop(sqp->desc->mon_desc);
+                               sqp->desc->houses = 0;
+                       }
+               }
+               if (cur_p->num_gojf)
+                       ret_card(cur_p);
+       }
+       for (i = player; i < num_play; i++) {
+               name_list[i] = name_list[i+1];
+               if (i + 1 < num_play)
+                       cpy_st(&play[i], &play[i+1], sizeof (PLAY));
+       }
+       name_list[num_play--] = 0;
+       for (i = 0; i < N_SQRS; i++)
+               if (board[i].owner > player)
+                       --board[i].owner;
+       player = --player < 0 ? num_play - 1 : player;
+       next_play();
+       if (num_play < 2) {
+               printf("\nThen %s WINS!!!!!\n", play[0].name);
+               printhold(0);
+               printf("That's a grand worth of $%d.\n",
+                       play[0].money+prop_worth(&play[0]));
+               exit(0);
+       }
+}