1 /*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)cards.c 8.1 (Berkeley) 05/31/93";
10 #endif /* not lint */
11
12 # include "monop.ext"
13 # include "pathnames.h"
14
15 /*
16 * These routine deal with the card decks
17 */
18
19 # define GOJF 'F' /* char for get-out-of-jail-free cards */
20
21 # ifndef DEV
22 static char *cardfile = _PATH_CARDS;
23 # else
24 static char *cardfile = "cards.pck";
25 # endif
26
27 static FILE *deckf;
28
29 /*
30 * This routine initializes the decks from the data file,
31 * which it opens.
32 */
init_decks()33 init_decks() {
34
35 if ((deckf=fopen(cardfile, "r")) == NULL) {
36 file_err:
37 perror(cardfile);
38 exit(1);
39 }
40 if (fread(deck, sizeof (DECK), 2, deckf) != 2)
41 goto file_err;
42 set_up(&CC_D);
43 set_up(&CH_D);
44 }
45 /*
46 * This routine sets up the offset pointers for the given deck.
47 */
set_up(dp)48 set_up(dp)
49 DECK *dp; {
50
51 reg int r1, r2;
52 int i;
53
54 dp->offsets = (long *) calloc(sizeof (long), dp->num_cards);
55 if (fread(dp->offsets, sizeof(long), dp->num_cards, deckf) != dp->num_cards) {
56 perror(cardfile);
57 exit(1);
58 }
59 dp->last_card = 0;
60 dp->gojf_used = FALSE;
61 for (i = 0; i < dp->num_cards; i++) {
62 reg long temp;
63
64 r1 = roll(1, dp->num_cards) - 1;
65 r2 = roll(1, dp->num_cards) - 1;
66 temp = dp->offsets[r2];
67 dp->offsets[r2] = dp->offsets[r1];
68 dp->offsets[r1] = temp;
69 }
70 }
71 /*
72 * This routine draws a card from the given deck
73 */
get_card(dp)74 get_card(dp)
75 DECK *dp; {
76
77 reg char type_maj, type_min;
78 reg int num;
79 int i, per_h, per_H, num_h, num_H;
80 OWN *op;
81
82 do {
83 fseek(deckf, dp->offsets[dp->last_card], 0);
84 dp->last_card = ++(dp->last_card) % dp->num_cards;
85 type_maj = getc(deckf);
86 } while (dp->gojf_used && type_maj == GOJF);
87 type_min = getc(deckf);
88 num = getw(deckf);
89 printmes();
90 switch (type_maj) {
91 case '+': /* get money */
92 if (type_min == 'A') {
93 for (i = 0; i < num_play; i++)
94 if (i != player)
95 play[i].money -= num;
96 num = num * (num_play - 1);
97 }
98 cur_p->money += num;
99 break;
100 case '-': /* lose money */
101 if (type_min == 'A') {
102 for (i = 0; i < num_play; i++)
103 if (i != player)
104 play[i].money += num;
105 num = num * (num_play - 1);
106 }
107 cur_p->money -= num;
108 break;
109 case 'M': /* move somewhere */
110 switch (type_min) {
111 case 'F': /* move forward */
112 num -= cur_p->loc;
113 if (num < 0)
114 num += 40;
115 break;
116 case 'J': /* move to jail */
117 goto_jail();
118 return;
119 case 'R': /* move to railroad */
120 spec = TRUE;
121 num = (int)((cur_p->loc + 5)/10)*10 + 5 - cur_p->loc;
122 break;
123 case 'U': /* move to utility */
124 spec = TRUE;
125 if (cur_p->loc >= 12 && cur_p->loc < 28)
126 num = 28 - cur_p->loc;
127 else {
128 num = 12 - cur_p->loc;
129 if (num < 0)
130 num += 40;
131 }
132 break;
133 case 'B':
134 num = -num;
135 break;
136 }
137 move(num);
138 break;
139 case 'T': /* tax */
140 if (dp == &CC_D) {
141 per_h = 40;
142 per_H = 115;
143 }
144 else {
145 per_h = 25;
146 per_H = 100;
147 }
148 num_h = num_H = 0;
149 for (op = cur_p->own_list; op; op = op->next)
150 if (op->sqr->type == PRPTY)
151 if (op->sqr->desc->houses == 5)
152 ++num_H;
153 else
154 num_h += op->sqr->desc->houses;
155 num = per_h * num_h + per_H * num_H;
156 printf("You had %d Houses and %d Hotels, so that cost you $%d\n", num_h, num_H, num);
157 if (num == 0)
158 lucky("");
159 else
160 cur_p->money -= num;
161 break;
162 case GOJF: /* get-out-of-jail-free card */
163 cur_p->num_gojf++;
164 dp->gojf_used = TRUE;
165 break;
166 }
167 spec = FALSE;
168 }
169 /*
170 * This routine prints out the message on the card
171 */
printmes()172 printmes() {
173
174 reg char c;
175
176 printline();
177 fflush(stdout);
178 while ((c = getc(deckf)) != '\0')
179 putchar(c);
180 printline();
181 fflush(stdout);
182 }
183