Home | History | Annotate | Line # | Download | only in monop
houses.c revision 1.13
      1 /*	$NetBSD: houses.c,v 1.13 2008/02/24 01:57:34 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 
     32 #include <sys/cdefs.h>
     33 #ifndef lint
     34 #if 0
     35 static char sccsid[] = "@(#)houses.c	8.1 (Berkeley) 5/31/93";
     36 #else
     37 __RCSID("$NetBSD: houses.c,v 1.13 2008/02/24 01:57:34 dholland Exp $");
     38 #endif
     39 #endif /* not lint */
     40 
     41 #include "monop.h"
     42 
     43 static const char	*names[N_MON+2];
     44 static char	cur_prop[80];
     45 
     46 static MON	*monops[N_MON];
     47 
     48 static void buy_h(MON *);
     49 static void sell_h(MON *);
     50 static void list_cur(MON *);
     51 static int avail_houses(void);
     52 static int avail_hotels(void);
     53 static bool can_only_buy_hotel(MON *);
     54 
     55 /*
     56  *	These routines deal with buying and selling houses
     57  */
     58 void
     59 buy_houses()
     60 {
     61 	int num_mon;
     62 	MON *mp;
     63 	OWN *op;
     64 	bool good, got_morg;
     65 	int i,p;
     66 
     67 over:
     68 	num_mon = 0;
     69 	good = TRUE;
     70 	got_morg = FALSE;
     71 	for (op = cur_p->own_list; op && op->sqr->type != PRPTY; op = op->next)
     72 		continue;
     73 	while (op)
     74 		if (op->sqr->desc->monop) {
     75 			mp = op->sqr->desc->mon_desc;
     76 			names[num_mon] = (monops[num_mon]=mp)->name;
     77 			num_mon++;
     78 			got_morg = good = FALSE;
     79 			for (i = 0; i < mp->num_in; i++) {
     80 				if (op->sqr->desc->morg)
     81 					got_morg = TRUE;
     82 				if (op->sqr->desc->houses != 5)
     83 					good = TRUE;
     84 				op = op->next;
     85 			}
     86 			if (!good || got_morg)
     87 				--num_mon;
     88 		}
     89 		else
     90 			op = op->next;
     91 	if (num_mon == 0) {
     92 		if (got_morg)
     93 			printf("You can't build on mortgaged monopolies.\n");
     94 		else if (!good)
     95 			printf("You can't build any more.\n");
     96 		else
     97 			printf("But you don't have any monopolies!!\n");
     98 		return;
     99 	}
    100 	if (num_mon == 1)
    101 		buy_h(monops[0]);
    102 	else {
    103 		names[num_mon++] = "done";
    104 		names[num_mon--] = 0;
    105 		if ((p = getinp(
    106 		    "Which property do you wish to buy houses for? ",
    107 		    names)) == num_mon)
    108 			return;
    109 		buy_h(monops[p]);
    110 		goto over;
    111 	}
    112 }
    113 
    114 static void
    115 buy_h(mnp)
    116 	MON *mnp;
    117 {
    118 	int i;
    119 	MON *mp;
    120 	int price;
    121 	short input[3],temp[3];
    122 	int tot, tot2;
    123 	PROP *pp;
    124 	int nhous, nhot;
    125 	bool chot;
    126 
    127 	mp = mnp;
    128 	price = mp->h_cost * 50;
    129 	nhous = avail_houses();
    130 	nhot = avail_hotels();
    131 	chot = can_only_buy_hotel(mnp);
    132 	if (nhous == 0 && !chot) {
    133 		printf("Building shortage:  no houses available.");
    134 		return;
    135 	}
    136 	if (nhot == 0 && chot) {
    137 		printf("Building shortage:  no hotels available.");
    138 		return;
    139 	}
    140 blew_it:
    141 	list_cur(mp);
    142 	printf("Houses will cost $%d\n", price);
    143 	printf("How many houses do you wish to buy for\n");
    144 	for (i = 0; i < mp->num_in; i++) {
    145 		pp = mp->sq[i]->desc;
    146 over:
    147 		if (pp->houses == 5) {
    148 			printf("%s (H):\n", mp->sq[i]->name);
    149 			input[i] = 0;
    150 			temp[i] = 5;
    151 			continue;
    152 		}
    153 		(void)snprintf(cur_prop, sizeof(cur_prop), "%s (%d): ",
    154 			mp->sq[i]->name, pp->houses);
    155 		input[i] = get_int(cur_prop);
    156 		temp[i] = input[i] + pp->houses;
    157 		if (temp[i] > 5 || temp[i] < 0) {
    158 			printf("That's too many.  The most you can buy is %d\n",
    159 			    5 - pp->houses);
    160 				goto over;
    161 			}
    162 	}
    163 	if (mp->num_in == 3 && (abs(temp[0] - temp[1]) > 1 ||
    164 	    abs(temp[0] - temp[2]) > 1 || abs(temp[1] - temp[2]) > 1)) {
    165 err:		printf("That makes the spread too wide.  Try again\n");
    166 		goto blew_it;
    167 	}
    168 	else if (mp->num_in == 2 && abs(temp[0] - temp[1]) > 1)
    169 		goto err;
    170 	for (tot = tot2 = i = 0; i < mp->num_in; i++) {
    171 		if (temp[i] == 5)
    172 			tot2++;
    173 		else
    174 			tot += input[i];
    175 	}
    176 	if (tot > nhous) {
    177 		printf(
    178 "You have asked for %d house%s but only %d are available.  Try again\n",
    179 		    tot, tot == 1 ? "":"s", nhous);
    180 		goto blew_it;
    181 	} else if (tot2 > nhot) {
    182 		printf(
    183 "You have asked for %d hotel%s but only %d are available.  Try again\n",
    184 		    tot2, tot2 == 1 ? "":"s", nhot);
    185 		goto blew_it;
    186 	}
    187 
    188 	if (tot) {
    189 		printf("You asked for %d house%s and %d hotel%s for $%d\n", tot,
    190 		    tot == 1 ? "" : "s", tot2, tot2 == 1 ? "" : "s", tot * price);
    191 		if (getyn("Is that ok? ") == 0) {
    192 			cur_p->money -= tot * price;
    193 			for (tot = i = 0; i < mp->num_in; i++)
    194 				mp->sq[i]->desc->houses = temp[i];
    195 		}
    196 	}
    197 }
    198 
    199 /*
    200  *	This routine sells houses.
    201  */
    202 void
    203 sell_houses()
    204 {
    205 	int num_mon;
    206 	MON *mp;
    207 	OWN *op;
    208 	bool good;
    209 	int p;
    210 
    211 over:
    212 	num_mon = 0;
    213 	good = TRUE;
    214 	for (op = cur_p->own_list; op;)
    215 		if (op->sqr->type == PRPTY && op->sqr->desc->monop) {
    216 			mp = op->sqr->desc->mon_desc;
    217 			names[num_mon] = (monops[num_mon]=mp)->name;
    218 			num_mon++;
    219 			good = 0;
    220 			do
    221 				if (!good && op->sqr->desc->houses != 0)
    222 					good = TRUE;
    223 			while (op->next && op->sqr->desc->mon_desc == mp
    224 			    && (op = op->next));
    225 			if (!good)
    226 				--num_mon;
    227 		} else
    228 			op = op->next;
    229 	if (num_mon == 0) {
    230 		printf("You don't have any houses to sell!!\n");
    231 		return;
    232 	}
    233 	if (num_mon == 1)
    234 		sell_h(monops[0]);
    235 	else {
    236 		names[num_mon++] = "done";
    237 		names[num_mon--] = 0;
    238 		if ((p = getinp(
    239 		    "Which property do you wish to sell houses from? ",
    240 		    names)) == num_mon)
    241 			return;
    242 		sell_h(monops[p]);
    243 		notify();
    244 		goto over;
    245 	}
    246 }
    247 
    248 static void
    249 sell_h(mnp)
    250 	MON *mnp;
    251 {
    252 	int i;
    253 	MON *mp;
    254 	int price;
    255 	short input[3],temp[3];
    256 	int tot;
    257 	PROP *pp;
    258 
    259 	mp = mnp;
    260 	price = mp->h_cost * 25;
    261 blew_it:
    262 	printf("Houses will get you $%d apiece\n", price);
    263 	list_cur(mp);
    264 	printf("How many houses do you wish to sell from\n");
    265 	for (i = 0; i < mp->num_in; i++) {
    266 		pp = mp->sq[i]->desc;
    267 over:
    268 		if (pp->houses == 0) {
    269 			printf("%s (0):\n", mp->sq[i]->name);
    270 			input[i] = temp[i] = 0;
    271 			continue;
    272 		}
    273 		if (pp->houses < 5)
    274 			(void)snprintf(cur_prop, sizeof(cur_prop), "%s (%d): ",
    275 				mp->sq[i]->name,pp->houses);
    276 		else
    277 			(void)snprintf(cur_prop, sizeof(cur_prop), "%s (H): ",
    278 				mp->sq[i]->name);
    279 		input[i] = get_int(cur_prop);
    280 		temp[i] = pp->houses - input[i];
    281 		if (temp[i] < 0) {
    282 			printf(
    283 			    "That's too many.  The most you can sell is %d\n",
    284 			    pp->houses);
    285 				goto over;
    286 			}
    287 	}
    288 	if (mp->num_in == 3 && (abs(temp[0] - temp[1]) > 1 ||
    289 	    abs(temp[0] - temp[2]) > 1 || abs(temp[1] - temp[2]) > 1)) {
    290 err:		printf("That makes the spread too wide.  Try again\n");
    291 		goto blew_it;
    292 	}
    293 	else if (mp->num_in == 2 && abs(temp[0] - temp[1]) > 1)
    294 		goto err;
    295 	for (tot = i = 0; i < mp->num_in; i++)
    296 		tot += input[i];
    297 	if (tot) {
    298 		printf("You asked to sell %d house%s for $%d\n", tot,
    299 		    tot == 1 ? "" : "s", tot * price);
    300 		if (getyn("Is that ok? ") == 0) {
    301 			cur_p->money += tot * price;
    302 			for (tot = i = 0; i < mp->num_in; i++)
    303 				mp->sq[i]->desc->houses = temp[i];
    304 		}
    305 	}
    306 }
    307 
    308 static void
    309 list_cur(mp)
    310 	MON *mp;
    311 {
    312 	int i;
    313 	SQUARE *sqp;
    314 
    315 	for (i = 0; i < mp->num_in; i++) {
    316 		sqp = mp->sq[i];
    317 		if (sqp->desc->houses == 5)
    318 			printf("%s (H) ", sqp->name);
    319 		else
    320 			printf("%s (%d) ", sqp->name, sqp->desc->houses);
    321 	}
    322 	putchar('\n');
    323 }
    324 
    325 static int
    326 avail_houses()
    327 {
    328 	int i, c;
    329 	SQUARE *sqp;
    330 
    331 	c = 0;
    332 	for (i = 0; i < N_SQRS; i++) {
    333 		sqp = &board[i];
    334 		if (sqp->type == PRPTY && sqp->owner >= 0 && sqp->desc->monop) {
    335 			if (sqp->desc->houses < 5 && sqp->desc->houses > 0)
    336 				c += sqp->desc->houses;
    337 		}
    338 	}
    339 	return(N_HOUSE - c);
    340 }
    341 
    342 static int
    343 avail_hotels()
    344 {
    345 	int i, c;
    346 	SQUARE *sqp;
    347 
    348 	c = 0;
    349 	for (i = 0; i < N_SQRS; i++) {
    350 		sqp = &board[i];
    351 		if (sqp->type == PRPTY && sqp->owner >= 0 && sqp->desc->monop) {
    352 			if (sqp->desc->houses == 5)
    353 				c++;
    354 		}
    355 	}
    356 	return(N_HOTEL - c);
    357 }
    358 
    359 static bool
    360 can_only_buy_hotel(mp)
    361 	MON	*mp;
    362 {
    363 	int i;
    364 
    365 	for (i = 0; i < mp->num_in; i++) {
    366 		if (mp->sq[i]->desc->houses < 4)
    367 			return(FALSE);
    368 	}
    369 	return(TRUE);
    370 }
    371