xref: /original-bsd/games/monop/trade.c (revision b4971bb3)
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[] = "@(#)trade.c	8.1 (Berkeley) 05/31/93";
10 #endif /* not lint */
11 
12 # include	"monop.ext"
13 
14 struct trd_st {			/* how much to give to other player	*/
15 	int	trader;			/* trader number		*/
16 	int	cash;			/* amount of cash 		*/
17 	int	gojf;			/* # get-out-of-jail-free cards	*/
18 	OWN	*prop_list;		/* property list		*/
19 };
20 
21 typedef	struct trd_st	TRADE;
22 
23 static char	*list[MAX_PRP+2];
24 
25 static int	used[MAX_PRP];
26 
27 static TRADE	trades[2];
28 
29 trade() {
30 
31 	reg int	tradee, i;
32 
33 	trading = TRUE;
34 	for (i = 0; i < 2; i++) {
35 		trades[i].cash = 0;
36 		trades[i].gojf = FALSE;
37 		trades[i].prop_list = NULL;
38 	}
39 over:
40 	if (num_play == 1) {
41 		printf("There ain't no-one around to trade WITH!!\n");
42 		return;
43 	}
44 	if (num_play > 2) {
45 		tradee = getinp("Which player do you wish to trade with? ",
46 		    name_list);
47 		if (tradee == num_play)
48 			return;
49 		if (tradee == player) {
50 			printf("You can't trade with yourself!\n");
51 			goto over;
52 		}
53 	}
54 	else
55 		tradee = 1 - player;
56 	get_list(0, player);
57 	get_list(1, tradee);
58 	if (getyn("Do you wish a summary? ") == 0)
59 		summate();
60 	if (getyn("Is the trade ok? ") == 0)
61 		do_trade();
62 }
63 /*
64  *	This routine gets the list of things to be trader for the
65  * player, and puts in the structure given.
66  */
67 get_list(struct_no, play_no)
68 int	struct_no, play_no; {
69 
70 	reg int		sn, pn;
71 	reg PLAY	*pp;
72 	int		numin, prop, num_prp;
73 	OWN		*op;
74 	TRADE		*tp;
75 
76 	for (numin = 0; numin < MAX_PRP; numin++)
77 		used[numin] = FALSE;
78 	sn = struct_no, pn = play_no;
79 	pp = &play[pn];
80 	tp = &trades[sn];
81 	tp->trader = pn;
82 	printf("player %s (%d):\n", pp->name, pn+1);
83 	if (pp->own_list) {
84 		numin = set_list(pp->own_list);
85 		for (num_prp = numin; num_prp; ) {
86 			prop = getinp("Which property do you wish to trade? ",
87 			    list);
88 			if (prop == numin)
89 				break;
90 			else if (used[prop])
91 				printf("You've already allocated that.\n");
92 			else {
93 				num_prp--;
94 				used[prop] = TRUE;
95 				for (op = pp->own_list; prop--; op = op->next)
96 					continue;
97 				add_list(pn, &(tp->prop_list), sqnum(op->sqr));
98 			}
99 		}
100 	}
101 	if (pp->money > 0) {
102 		printf("You have $%d.  ", pp->money);
103 		tp->cash = get_int("How much are you trading? ");
104 	}
105 	if (pp->num_gojf > 0) {
106 once_more:
107 		printf("You have %d get-out-of-jail-free cards. ",pp->num_gojf);
108 		tp->gojf = get_int("How many are you trading? ");
109 		if (tp->gojf > pp->num_gojf) {
110 			printf("You don't have that many.  Try again.\n");
111 			goto once_more;
112 		}
113 	}
114 }
115 /*
116  *	This routine sets up the list of tradable property.
117  */
118 set_list(the_list)
119 reg OWN	*the_list; {
120 
121 	reg int	i;
122 	reg OWN	*op;
123 
124 	i = 0;
125 	for (op = the_list; op; op = op->next)
126 		if (!used[i])
127 			list[i++] = op->sqr->name;
128 	list[i++] = "done";
129 	list[i--] = 0;
130 	return i;
131 }
132 /*
133  *	This routine summates the trade.
134  */
135 summate() {
136 
137 	reg bool	some;
138 	reg int		i;
139 	reg TRADE	*tp;
140 	OWN	*op;
141 
142 	for (i = 0; i < 2; i++) {
143 		tp = &trades[i];
144 		some = FALSE;
145 		printf("Player %s (%d) gives:\n", play[tp->trader].name,
146 			tp->trader+1);
147 		if (tp->cash > 0)
148 			printf("\t$%d\n", tp->cash), some++;
149 		if (tp->gojf > 0)
150 			printf("\t%d get-out-of-jail-free card(s)\n", tp->gojf),
151 			some++;
152 		if (tp->prop_list) {
153 			for (op = tp->prop_list; op; op = op->next)
154 				putchar('\t'), printsq(sqnum(op->sqr), TRUE);
155 			some++;
156 		}
157 		if (!some)
158 			printf("\t-- Nothing --\n");
159 	}
160 }
161 /*
162  *	This routine actually executes the trade.
163  */
164 do_trade() {
165 
166 	move_em(&trades[0], &trades[1]);
167 	move_em(&trades[1], &trades[0]);
168 }
169 /*
170  *	This routine does a switch from one player to another
171  */
172 move_em(from, to)
173 TRADE	*from, *to; {
174 
175 	reg PLAY	*pl_fr, *pl_to;
176 	reg OWN		*op;
177 
178 	pl_fr = &play[from->trader];
179 	pl_to = &play[to->trader];
180 
181 	pl_fr->money -= from->cash;
182 	pl_to->money += from->cash;
183 	pl_fr->num_gojf -= from->gojf;
184 	pl_to->num_gojf += from->gojf;
185 	for (op = from->prop_list; op; op = op->next) {
186 		add_list(to->trader, &(pl_to->own_list), sqnum(op->sqr));
187 		op->sqr->owner = to->trader;
188 		del_list(from->trader, &(pl_fr->own_list), sqnum(op->sqr));
189 	}
190 	set_ownlist(to->trader);
191 }
192 /*
193  *	This routine lets a player resign
194  */
195 resign() {
196 
197 	reg int	i, new_own;
198 	reg OWN	*op;
199 	SQUARE	*sqp;
200 
201 	if (cur_p->money <= 0) {
202 		switch (board[cur_p->loc].type) {
203 		  case UTIL:
204 		  case RR:
205 		  case PRPTY:
206 			new_own = board[cur_p->loc].owner;
207 			break;
208 		  default:		/* Chance, taxes, etc */
209 			new_own = num_play;
210 			break;
211 		}
212 		if (new_own == num_play)
213 			printf("You would resign to the bank\n");
214 		else
215 			printf("You would resign to %s\n", name_list[new_own]);
216 	}
217 	else if (num_play == 1) {
218 		new_own = num_play;
219 		printf("You would resign to the bank\n");
220 	}
221 	else {
222 		name_list[num_play] = "bank";
223 		do {
224 			new_own = getinp("Who do you wish to resign to? ",
225 			    name_list);
226 			if (new_own == player)
227 				printf("You can't resign to yourself!!\n");
228 		} while (new_own == player);
229 		name_list[num_play] = "done";
230 	}
231 	if (getyn("Do you really want to resign? ", yn) != 0)
232 		return;
233 	if (num_play == 1) {
234 		printf("Then NOBODY wins (not even YOU!)\n");
235 		exit(0);
236 	}
237 	if (new_own < num_play) {	/* resign to player		*/
238 		printf("resigning to player\n");
239 		trades[0].trader = new_own;
240 		trades[0].cash = trades[0].gojf = 0;
241 		trades[0].prop_list = NULL;
242 		trades[1].trader = player;
243 		trades[1].cash = cur_p->money > 0 ? cur_p->money : 0;
244 		trades[1].gojf = cur_p->num_gojf;
245 		trades[1].prop_list = cur_p->own_list;
246 		do_trade();
247 	}
248 	else {				/* resign to bank		*/
249 		printf("resigning to bank\n");
250 		for (op = cur_p->own_list; op; op = op->next) {
251 			sqp = op->sqr;
252 			sqp->owner = -1;
253 			sqp->desc->morg = FALSE;
254 			if (sqp->type == PRPTY) {
255 				isnot_monop(sqp->desc->mon_desc);
256 				sqp->desc->houses = 0;
257 			}
258 		}
259 		if (cur_p->num_gojf)
260 			ret_card(cur_p);
261 	}
262 	for (i = player; i < num_play; i++) {
263 		name_list[i] = name_list[i+1];
264 		if (i + 1 < num_play)
265 			cpy_st(&play[i], &play[i+1], sizeof (PLAY));
266 	}
267 	name_list[num_play--] = 0;
268 	for (i = 0; i < N_SQRS; i++)
269 		if (board[i].owner > player)
270 			--board[i].owner;
271 	player = --player < 0 ? num_play - 1 : player;
272 	next_play();
273 	if (num_play < 2) {
274 		printf("\nThen %s WINS!!!!!\n", play[0].name);
275 		printhold(0);
276 		printf("That's a grand worth of $%d.\n",
277 			play[0].money+prop_worth(&play[0]));
278 		exit(0);
279 	}
280 }
281