(linenum→info "unix/slp.c:2238")

bsd-games/2.17/monop/cards.c

    1: /*      $NetBSD: cards.c,v 1.14 2004/01/27 20:30:30 jsm Exp $        */
    2: 
    3: /*
    4:  * Copyright (c) 1980, 1993
    5:  *      The Regents of the University of California.  All rights reserved.
    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.
   15:  * 3. Neither the name of the University nor the names of its contributors
   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: 
   32: #include <sys/cdefs.h>
   33: #ifndef lint
   34: #if 0
   35: static char sccsid[] = "@(#)cards.c     8.1 (Berkeley) 5/31/93";
   36: #else
   37: __RCSID("$NetBSD: cards.c,v 1.14 2004/01/27 20:30:30 jsm Exp $");
   38: #endif
   39: #endif /* not lint */
   40: 
   41: #include <sys/types.h>
   42: #include <sys/endian.h>
   43: #include "monop.ext"
   44: #include "pathnames.h"
   45: 
   46: /*
   47:  *      These routine deal with the card decks
   48:  */
   49: 
   50: #define GOJF    'F'        /* char for get-out-of-jail-free cards */
   51: 
   52: #ifndef DEV
   53: static const char       *cardfile     = _PATH_CARDS;
   54: #else
   55: static const char       *cardfile     = "cards.pck";
   56: #endif
   57: 
   58: static FILE     *deckf;
   59: 
   60: static void set_up(DECK *);
   61: static void printmes(void);
   62: 
   63: /*
   64:  *      This routine initializes the decks from the data file,
   65:  * which it opens.
   66:  */
   67: void
   68: init_decks()
   69: {
   70:         int32_t nc;
   71: 
   72:         if ((deckf=fopen(cardfile, "r")) == NULL) {
   73: file_err:
   74:                 perror(cardfile);
   75:                 exit(1);
   76:         }
   77: 
   78:         /* read number of community chest cards... */
   79:         if (fread(&nc, sizeof(nc), 1, deckf) != 1)
   80:                 goto file_err;
   81:         CC_D.num_cards = be32toh(nc);
   82:         /* ... and number of community chest cards. */
   83:         if (fread(&nc, sizeof(nc), 1, deckf) != 1)
   84:                 goto file_err;
   85:         CH_D.num_cards = be32toh(nc);
   86:         set_up(&CC_D);
   87:         set_up(&CH_D);
   88: }
   89: 
   90: /*
   91:  *      This routine sets up the offset pointers for the given deck.
   92:  */
   93: static void
   94: set_up(dp)
   95:         DECK *dp;
   96: {
   97:         int r1, r2;
   98:         int i;
   99: 
  100:         dp->offsets = (u_int64_t *) calloc(dp->num_cards, sizeof (u_int64_t));
  101:         if (dp->offsets == NULL)
  102:                 err(1, NULL);
  103:         if (fread(dp->offsets, sizeof(u_int64_t), dp->num_cards, deckf) !=
  104:             (size_t)dp->num_cards) {
  105:                 perror(cardfile);
  106:                 exit(1);
  107:         }
  108:         /* convert offsets from big-endian byte order */
  109:         for (i = 0; i < dp->num_cards; i++)
  110:                 BE64TOH(dp->offsets[i]);
  111:         dp->last_card = 0;
  112:         dp->gojf_used = FALSE;
  113:         for (i = 0; i < dp->num_cards; i++) {
  114:                 u_int64_t     temp;
  115: 
  116:                 r1 = roll(1, dp->num_cards) - 1;
  117:                 r2 = roll(1, dp->num_cards) - 1;
  118:                 temp = dp->offsets[r2];
  119:                 dp->offsets[r2] = dp->offsets[r1];
  120:                 dp->offsets[r1] = temp;
  121:         }
  122: }
  123: 
  124: /*
  125:  *      This routine draws a card from the given deck
  126:  */
  127: void
  128: get_card(dp)
  129:         DECK *dp;
  130: {
  131:         char type_maj, type_min;
  132:         int num;
  133:         int i, per_h, per_H, num_h, num_H;
  134:         OWN *op;
  135: 
  136:         do {
  137:                 fseek(deckf, dp->offsets[dp->last_card], SEEK_SET);
  138:                 dp->last_card = ++(dp->last_card) % dp->num_cards;
  139:                 type_maj = getc(deckf);
  140:         } while (dp->gojf_used && type_maj == GOJF);
  141:         type_min = getc(deckf);
  142:         num = ntohl(getw(deckf));
  143:         printmes();
  144:         switch (type_maj) {
  145:           case '+':            /* get money              */
  146:                 if (type_min == 'A') {
  147:                         for (i = 0; i < num_play; i++)
  148:                                 if (i != player)
  149:                                         play[i].money -= num;
  150:                         num = num * (num_play - 1);
  151:                 }
  152:                 cur_p->money += num;
  153:                 break;
  154:           case '-':            /* lose money             */
  155:                 if (type_min == 'A') {
  156:                         for (i = 0; i < num_play; i++)
  157:                                 if (i != player)
  158:                                         play[i].money += num;
  159:                         num = num * (num_play - 1);
  160:                 }
  161:                 cur_p->money -= num;
  162:                 break;
  163:           case 'M':            /* move somewhere */
  164:                 switch (type_min) {
  165:                   case 'F':           /* move forward  */
  166:                         num -= cur_p->loc;
  167:                         if (num < 0)
  168:                                 num += 40;
  169:                         break;
  170:                   case 'J':           /* move to jail  */
  171:                         goto_jail();
  172:                         return;
  173:                   case 'R':           /* move to railroad      */
  174:                         spec = TRUE;
  175:                         num = (int)((cur_p->loc + 5)/10)*10 + 5 - cur_p->loc;
  176:                         break;
  177:                   case 'U':           /* move to utility       */
  178:                         spec = TRUE;
  179:                         if (cur_p->loc >= 12 && cur_p->loc < 28)
  180:                                 num = 28 - cur_p->loc;
  181:                         else {
  182:                                 num = 12 - cur_p->loc;
  183:                                 if (num < 0)
  184:                                         num += 40;
  185:                         }
  186:                         break;
  187:                   case 'B':
  188:                         num = -num;
  189:                         break;
  190:                 }
  191:                 move(num);
  192:                 break;
  193:           case 'T':                    /* tax                   */
  194:                 if (dp == &CC_D) {
  195:                         per_h = 40;
  196:                         per_H = 115;
  197:                 }
  198:                 else {
  199:                         per_h = 25;
  200:                         per_H = 100;
  201:                 }
  202:                 num_h = num_H = 0;
  203:                 for (op = cur_p->own_list; op; op = op->next)
  204:                         if (op->sqr->type == PRPTY) {
  205:                                 if (op->sqr->desc->houses == 5)
  206:                                         ++num_H;
  207:                                 else
  208:                                         num_h += op->sqr->desc->houses;
  209:                         }
  210:                 num = per_h * num_h + per_H * num_H;
  211:                 printf(
  212:                     "You had %d Houses and %d Hotels, so that cost you $%d\n",
  213:                     num_h, num_H, num);
  214:                 if (num == 0)
  215:                         lucky("");
  216:                 else
  217:                         cur_p->money -= num;
  218:                 break;
  219:           case GOJF:           /* get-out-of-jail-free card     */
  220:                 cur_p->num_gojf++;
  221:                 dp->gojf_used = TRUE;
  222:                 break;
  223:         }
  224:         spec = FALSE;
  225: }
  226: 
  227: /*
  228:  *      This routine prints out the message on the card
  229:  */
  230: static void
  231: printmes()
  232: {
  233:         char c;
  234: 
  235:         printline();
  236:         fflush(stdout);
  237:         while ((c = getc(deckf)) != '\0')
  238:                 putchar(c);
  239:         printline();
  240:         fflush(stdout);
  241: }
Syntax (Markdown)