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