xref: /original-bsd/games/monop/cards.c (revision af60fb2a)
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  */
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  */
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  */
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  */
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