1 /* $NetBSD: trade.c,v 1.16 2012/06/19 05:35:32 dholland Exp $ */ 2 3 /* 4 * Copyright (c) 1980, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)trade.c 8.1 (Berkeley) 5/31/93 32 */ 33 34 #include "monop.h" 35 36 struct trd_st { /* how much to give to other player */ 37 int trader; /* trader number */ 38 int cash; /* amount of cash */ 39 int gojf; /* # get-out-of-jail-free cards */ 40 OWN *prop_list; /* property list */ 41 }; 42 43 typedef struct trd_st TRADE; 44 45 static const char *plist[MAX_PRP+2]; 46 47 static int used[MAX_PRP]; 48 49 static TRADE trades[2]; 50 51 static void get_list(int, int ); 52 static int set_list(OWN *); 53 static void summate(void); 54 static void do_trade(void); 55 static void move_em(TRADE *, TRADE *); 56 57 void 58 trade(void) 59 { 60 int tradee, i; 61 62 trading = TRUE; 63 for (i = 0; i < 2; i++) { 64 trades[i].cash = 0; 65 trades[i].gojf = FALSE; 66 trades[i].prop_list = NULL; 67 } 68 over: 69 if (num_play == 1) { 70 printf("There ain't no-one around to trade WITH!!\n"); 71 return; 72 } 73 if (num_play > 2) { 74 tradee = getinp("Which player do you wish to trade with? ", 75 name_list); 76 if (tradee == num_play) 77 return; 78 if (tradee == player) { 79 printf("You can't trade with yourself!\n"); 80 goto over; 81 } 82 } 83 else 84 tradee = 1 - player; 85 get_list(0, player); 86 get_list(1, tradee); 87 if (getyn("Do you wish a summary? ") == 0) 88 summate(); 89 if (getyn("Is the trade ok? ") == 0) 90 do_trade(); 91 } 92 93 /* 94 * This routine gets the list of things to be trader for the 95 * player, and puts in the structure given. 96 */ 97 static void 98 get_list(int struct_no, int play_no) 99 { 100 int sn, pn; 101 PLAY *pp; 102 int numin, propnum, num_prp; 103 OWN *op; 104 TRADE *tp; 105 106 for (numin = 0; numin < MAX_PRP; numin++) 107 used[numin] = FALSE; 108 sn = struct_no, pn = play_no; 109 pp = &play[pn]; 110 tp = &trades[sn]; 111 tp->trader = pn; 112 printf("player %s (%d):\n", pp->name, pn+1); 113 if (pp->own_list) { 114 numin = set_list(pp->own_list); 115 for (num_prp = numin; num_prp; ) { 116 propnum=getinp("Which property do you wish to trade? ", 117 plist); 118 if (propnum == numin) 119 break; 120 else if (used[propnum]) 121 printf("You've already allocated that.\n"); 122 else { 123 num_prp--; 124 used[propnum] = TRUE; 125 for (op = pp->own_list; propnum--; op = op->next) 126 continue; 127 add_list(pn, &(tp->prop_list), sqnum(op->sqr)); 128 } 129 } 130 } 131 if (pp->money > 0) { 132 printf("You have $%d. ", pp->money); 133 tp->cash = get_int("How much are you trading? "); 134 } 135 if (pp->num_gojf > 0) { 136 once_more: 137 printf("You have %d get-out-of-jail-free cards. ",pp->num_gojf); 138 tp->gojf = get_int("How many are you trading? "); 139 if (tp->gojf > pp->num_gojf) { 140 printf("You don't have that many. Try again.\n"); 141 goto once_more; 142 } 143 } 144 } 145 146 /* 147 * This routine sets up the list of tradable property. 148 */ 149 static int 150 set_list(OWN *the_list) 151 { 152 int i; 153 OWN *op; 154 155 i = 0; 156 for (op = the_list; op; op = op->next) 157 if (!used[i]) 158 plist[i++] = op->sqr->name; 159 plist[i++] = "done"; 160 plist[i--] = 0; 161 return i; 162 } 163 164 /* 165 * This routine summates the trade. 166 */ 167 static void 168 summate(void) 169 { 170 bool some; 171 int i; 172 TRADE *tp; 173 OWN *op; 174 175 for (i = 0; i < 2; i++) { 176 tp = &trades[i]; 177 some = FALSE; 178 printf("Player %s (%d) gives:\n", play[tp->trader].name, 179 tp->trader+1); 180 if (tp->cash > 0) 181 printf("\t$%d\n", tp->cash), some++; 182 if (tp->gojf > 0) 183 printf("\t%d get-out-of-jail-free card(s)\n", tp->gojf), 184 some++; 185 if (tp->prop_list) { 186 for (op = tp->prop_list; op; op = op->next) 187 putchar('\t'), printsq(sqnum(op->sqr), TRUE); 188 some++; 189 } 190 if (!some) 191 printf("\t-- Nothing --\n"); 192 } 193 } 194 195 /* 196 * This routine actually executes the trade. 197 */ 198 static void 199 do_trade(void) 200 { 201 move_em(&trades[0], &trades[1]); 202 move_em(&trades[1], &trades[0]); 203 } 204 205 /* 206 * This routine does a switch from one player to another 207 */ 208 static void 209 move_em(TRADE *from, TRADE *to) 210 { 211 PLAY *pl_fr, *pl_to; 212 OWN *op; 213 214 pl_fr = &play[from->trader]; 215 pl_to = &play[to->trader]; 216 217 pl_fr->money -= from->cash; 218 pl_to->money += from->cash; 219 pl_fr->num_gojf -= from->gojf; 220 pl_to->num_gojf += from->gojf; 221 for (op = from->prop_list; op; op = op->next) { 222 add_list(to->trader, &(pl_to->own_list), sqnum(op->sqr)); 223 op->sqr->owner = to->trader; 224 del_list(from->trader, &(pl_fr->own_list), sqnum(op->sqr)); 225 } 226 set_ownlist(to->trader); 227 } 228 229 /* 230 * This routine lets a player resign 231 */ 232 void 233 resign(void) 234 { 235 int i, new_own; 236 OWN *op; 237 SQUARE *sqp; 238 239 if (cur_p->money <= 0) { 240 switch (board[cur_p->loc].type) { 241 case UTIL: 242 case RR: 243 case PRPTY: 244 new_own = board[cur_p->loc].owner; 245 /* If you ran out of money by buying current location */ 246 if (new_own == player) 247 new_own = num_play; 248 break; 249 default: /* Chance, taxes, etc */ 250 new_own = num_play; 251 break; 252 } 253 if (new_own == num_play) 254 printf("You would resign to the bank\n"); 255 else 256 printf("You would resign to %s\n", name_list[new_own]); 257 } 258 else if (num_play == 1) { 259 new_own = num_play; 260 printf("You would resign to the bank\n"); 261 } 262 else { 263 name_list[num_play] = "bank"; 264 do { 265 new_own = getinp("Who do you wish to resign to? ", 266 name_list); 267 if (new_own == player) 268 printf("You can't resign to yourself!!\n"); 269 } while (new_own == player); 270 name_list[num_play] = "done"; 271 } 272 if (getyn("Do you really want to resign? ") != 0) 273 return; 274 if (num_play == 1) { 275 printf("Then NOBODY wins (not even YOU!)\n"); 276 exit(0); 277 } 278 if (new_own < num_play) { /* resign to player */ 279 printf("resigning to player\n"); 280 trades[0].trader = new_own; 281 trades[0].cash = trades[0].gojf = 0; 282 trades[0].prop_list = NULL; 283 trades[1].trader = player; 284 trades[1].cash = cur_p->money > 0 ? cur_p->money : 0; 285 trades[1].gojf = cur_p->num_gojf; 286 trades[1].prop_list = cur_p->own_list; 287 do_trade(); 288 } 289 else { /* resign to bank */ 290 printf("resigning to bank\n"); 291 for (op = cur_p->own_list; op; op = op->next) { 292 sqp = op->sqr; 293 sqp->owner = -1; 294 sqp->desc->morg = FALSE; 295 if (sqp->type == PRPTY) { 296 is_not_monop(sqp->desc->mon_desc); 297 sqp->desc->houses = 0; 298 } 299 } 300 if (cur_p->num_gojf) 301 ret_card(cur_p); 302 } 303 free(play[player].name); 304 for (i = player; i < num_play; i++) { 305 name_list[i] = name_list[i+1]; 306 if (i + 1 < num_play) 307 play[i] = play[i+1]; 308 } 309 name_list[num_play--] = NULL; 310 for (i = 0; i < N_SQRS; i++) 311 if (board[i].owner > player) 312 --board[i].owner; 313 player = player == 0 ? num_play - 1 : player - 1; 314 next_play(); 315 if (num_play < 2) { 316 printf("\nThen %s WINS!!!!!\n", play[0].name); 317 printhold(0); 318 printf("That's a grand worth of $%d.\n", 319 play[0].money+prop_worth(&play[0])); 320 exit(0); 321 } 322 } 323