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