xref: /netbsd-src/games/monop/misc.c (revision c34afa686bf074a6dcc7f17157faae72111dde9a)
1*c34afa68Sdholland /*	$NetBSD: misc.c,v 1.23 2012/06/19 05:35:32 dholland Exp $	*/
242fb1b9dScgd 
361f28255Scgd /*
442fb1b9dScgd  * Copyright (c) 1980, 1993
542fb1b9dScgd  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
15e5aeb4eaSagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
32b118ad22Schristos #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
3442fb1b9dScgd #if 0
3542fb1b9dScgd static char sccsid[] = "@(#)misc.c	8.1 (Berkeley) 5/31/93";
3642fb1b9dScgd #else
37*c34afa68Sdholland __RCSID("$NetBSD: misc.c,v 1.23 2012/06/19 05:35:32 dholland Exp $");
3842fb1b9dScgd #endif
3961f28255Scgd #endif /* not lint */
4061f28255Scgd 
4161f28255Scgd #include <ctype.h>
425ed7a710Sdholland #include <limits.h>
4361f28255Scgd #include <signal.h>
447cafbb8eSchristos #include <errno.h>
4561f28255Scgd 
46b51259daSdholland #include "monop.h"
47b51259daSdholland 
48f2a20f5fSdholland static void is_monop(MON *, int);
49f2a20f5fSdholland 
5061f28255Scgd /*
5161f28255Scgd  *	This routine executes a truncated set of commands until a
5261f28255Scgd  * "yes or "no" answer is gotten.
5361f28255Scgd  */
54b118ad22Schristos int
getyn(const char * prompt)55*c34afa68Sdholland getyn(const char *prompt)
56b118ad22Schristos {
57b118ad22Schristos 	int com;
5861f28255Scgd 
5961f28255Scgd 	for (;;)
601a8a5d79Sjsm 		if ((com=getinp(prompt, yncoms)) < 2)
6161f28255Scgd 			return com;
6261f28255Scgd 		else
6361f28255Scgd 			(*func[com-2])();
6461f28255Scgd }
65e42b2048Ssimonb 
6661f28255Scgd /*
6761f28255Scgd  *	This routine tells the player if he's out of money.
6861f28255Scgd  */
69b118ad22Schristos void
notify(void)70*c34afa68Sdholland notify(void)
71b118ad22Schristos {
7261f28255Scgd 	if (cur_p->money < 0)
7361f28255Scgd 		printf("That leaves you $%d in debt\n", -cur_p->money);
7461f28255Scgd 	else if (cur_p->money == 0)
7561f28255Scgd 		printf("that leaves you broke\n");
7661f28255Scgd 	else if (fixing && !told_em && cur_p->money > 0) {
7761f28255Scgd 		printf("-- You are now Solvent ---\n");
7861f28255Scgd 		told_em = TRUE;
7961f28255Scgd 	}
8061f28255Scgd }
81e42b2048Ssimonb 
8261f28255Scgd /*
8361f28255Scgd  *	This routine switches to the next player
8461f28255Scgd  */
85b118ad22Schristos void
next_play(void)86*c34afa68Sdholland next_play(void)
87b118ad22Schristos {
889cfe468cScgd 	player = (player + 1) % num_play;
8961f28255Scgd 	cur_p = &play[player];
9061f28255Scgd 	num_doub = 0;
9161f28255Scgd }
92e42b2048Ssimonb 
9361f28255Scgd /*
9461f28255Scgd  *	This routine gets an integer from the keyboard after the
9561f28255Scgd  * given prompt.
9661f28255Scgd  */
97b118ad22Schristos int
get_int(const char * prompt)98*c34afa68Sdholland get_int(const char *prompt)
99b118ad22Schristos {
1005ed7a710Sdholland 	long num;
101b118ad22Schristos 	char *sp;
10261f28255Scgd 	char buf[257];
10361f28255Scgd 
10461f28255Scgd 	for (;;) {
105fff414b8Sdholland 		printf("%s", prompt);
1065ed7a710Sdholland 		fgets(buf, sizeof(buf), stdin);
107c509c631Sahoka 		/* if stdin is closed we cant really play anymore */
1085ed7a710Sdholland 		if (feof(stdin))
109c509c631Sahoka 			quit();
1105ed7a710Sdholland 		sp = strchr(buf, '\n');
1115ed7a710Sdholland 		if (sp)
1125ed7a710Sdholland 			*sp = '\0';
1135ed7a710Sdholland 		errno = 0;
1145ed7a710Sdholland 		num = strtol(buf, &sp, 10);
1155ed7a710Sdholland 		if (errno || strlen(sp) > 0 || num < 0 || num >= INT_MAX) {
11661f28255Scgd 			printf("I can't understand that\n");
1175ed7a710Sdholland 			continue;
1185ed7a710Sdholland 		}
1195ed7a710Sdholland 		return num;
12061f28255Scgd 	}
12161f28255Scgd }
122e42b2048Ssimonb 
12361f28255Scgd /*
12461f28255Scgd  *	This routine sets the monopoly flag from the list given.
12561f28255Scgd  */
126b118ad22Schristos void
set_ownlist(int pl)127*c34afa68Sdholland set_ownlist(int pl)
128b118ad22Schristos {
129b118ad22Schristos 	int num;		/* general counter		*/
130b118ad22Schristos 	MON *orig;		/* remember starting monop ptr	*/
131b118ad22Schristos 	OWN *op;		/* current owned prop		*/
1325538b1ccSdholland 	OWN *orig_op;		/* original prop before loop	*/
13361f28255Scgd 
13461f28255Scgd 	op = play[pl].own_list;
13561f28255Scgd #ifdef DEBUG
136eefb74f4Sdholland 	printf("op [%p] = play[pl [%d] ].own_list;\n", op, pl);
13761f28255Scgd #endif
13861f28255Scgd 	while (op) {
13961f28255Scgd #ifdef DEBUG
14061f28255Scgd 		printf("op->sqr->type = %d\n", op->sqr->type);
14161f28255Scgd #endif
14261f28255Scgd 		switch (op->sqr->type) {
14361f28255Scgd 		  case UTIL:
14461f28255Scgd #ifdef DEBUG
14561f28255Scgd 			printf("  case UTIL:\n");
14661f28255Scgd #endif
147e42b2048Ssimonb 			for (num = 0; op && op->sqr->type == UTIL;
148e42b2048Ssimonb 			    op = op->next)
14961f28255Scgd 				num++;
15061f28255Scgd 			play[pl].num_util = num;
15161f28255Scgd #ifdef DEBUG
15261f28255Scgd 			printf("play[pl].num_util = num [%d];\n", num);
15361f28255Scgd #endif
15461f28255Scgd 			break;
15561f28255Scgd 		  case RR:
15661f28255Scgd #ifdef DEBUG
15761f28255Scgd 			printf("  case RR:\n");
15861f28255Scgd #endif
159e42b2048Ssimonb 			for (num = 0; op && op->sqr->type == RR;
160e42b2048Ssimonb 			    op = op->next) {
16161f28255Scgd #ifdef DEBUG
16261f28255Scgd 				printf("iter: %d\n", num);
163eefb74f4Sdholland 				printf("op = %p, op->sqr = %p, "
164e42b2048Ssimonb 				    "op->sqr->type = %d\n", op, op->sqr,
165e42b2048Ssimonb 				    op->sqr->type);
16661f28255Scgd #endif
16761f28255Scgd 				num++;
16861f28255Scgd 			}
16961f28255Scgd 			play[pl].num_rr = num;
17061f28255Scgd #ifdef DEBUG
17161f28255Scgd 			printf("play[pl].num_rr = num [%d];\n", num);
17261f28255Scgd #endif
17361f28255Scgd 			break;
17461f28255Scgd 		  case PRPTY:
17561f28255Scgd #ifdef DEBUG
17661f28255Scgd 			printf("  case PRPTY:\n");
17761f28255Scgd #endif
17861f28255Scgd 			orig = op->sqr->desc->mon_desc;
17961f28255Scgd 			orig_op = op;
18061f28255Scgd 			num = 0;
18161f28255Scgd 			while (op && op->sqr->desc->mon_desc == orig) {
18261f28255Scgd #ifdef DEBUG
18361f28255Scgd 				printf("iter: %d\n", num);
18461f28255Scgd #endif
18561f28255Scgd 				num++;
18661f28255Scgd #ifdef DEBUG
18761f28255Scgd 				printf("op = op->next ");
18861f28255Scgd #endif
18961f28255Scgd 				op = op->next;
19061f28255Scgd #ifdef DEBUG
191eefb74f4Sdholland 				printf("[%p];\n", op);
19261f28255Scgd #endif
19361f28255Scgd 			}
19461f28255Scgd #ifdef DEBUG
195eefb74f4Sdholland 			printf("num = %d\n", num);
19661f28255Scgd #endif
197eefb74f4Sdholland 			if (orig == NULL) {
198e42b2048Ssimonb 				printf("panic:  bad monopoly descriptor: "
199e42b2048Ssimonb 				    "orig = %p\n", orig);
20061f28255Scgd 				printf("player # %d\n", pl+1);
20161f28255Scgd 				printhold(pl);
202b118ad22Schristos 				printf("orig_op = %p\n", orig_op);
203db0d7197Schristos 				if (orig_op) {
204e42b2048Ssimonb 					printf("orig_op->sqr->type = %d (PRPTY)\n",
205db0d7197Schristos 					    orig_op->sqr->type);
206eefb74f4Sdholland 					printf("orig_op->next = %p\n",
207eefb74f4Sdholland 					    orig_op->next);
208e42b2048Ssimonb 					printf("orig_op->sqr->desc = %p\n",
209db0d7197Schristos 					    orig_op->sqr->desc);
210db0d7197Schristos 				}
211b118ad22Schristos 				printf("op = %p\n", op);
212db0d7197Schristos 				if (op) {
213e42b2048Ssimonb 					printf("op->sqr->type = %d (PRPTY)\n",
214e42b2048Ssimonb 					    op->sqr->type);
215b118ad22Schristos 					printf("op->next = %p\n", op->next);
216db0d7197Schristos 					printf("op->sqr->desc = %p\n",
217db0d7197Schristos 					    op->sqr->desc);
218db0d7197Schristos 				}
21961f28255Scgd 				printf("num = %d\n", num);
2205ed7a710Sdholland 				exit(1);
22161f28255Scgd 			}
22261f28255Scgd #ifdef DEBUG
22361f28255Scgd 			printf("orig->num_in = %d\n", orig->num_in);
22461f28255Scgd #endif
22561f28255Scgd 			if (num == orig->num_in)
22661f28255Scgd 				is_monop(orig, pl);
22761f28255Scgd 			else
228ce5670f7Sjsm 				is_not_monop(orig);
22961f28255Scgd 			break;
23061f28255Scgd 		}
23161f28255Scgd 	}
23261f28255Scgd }
233e42b2048Ssimonb 
23461f28255Scgd /*
23561f28255Scgd  *	This routine sets things up as if it is a new monopoly
23661f28255Scgd  */
237f2a20f5fSdholland static void
is_monop(MON * mp,int pl)238*c34afa68Sdholland is_monop(MON *mp, int pl)
239b118ad22Schristos {
240b118ad22Schristos 	int i;
24161f28255Scgd 
24261f28255Scgd 	mp->owner = pl;
24361f28255Scgd 	mp->num_own = mp->num_in;
24461f28255Scgd 	for (i = 0; i < mp->num_in; i++)
24561f28255Scgd 		mp->sq[i]->desc->monop = TRUE;
24661f28255Scgd 	mp->name = mp->mon_n;
24761f28255Scgd }
248e42b2048Ssimonb 
24961f28255Scgd /*
25061f28255Scgd  *	This routine sets things up as if it is no longer a monopoly
25161f28255Scgd  */
252b118ad22Schristos void
is_not_monop(MON * mp)253*c34afa68Sdholland is_not_monop(MON *mp)
254b118ad22Schristos {
255b118ad22Schristos 	int i;
25661f28255Scgd 
25761f28255Scgd 	mp->owner = -1;
25861f28255Scgd 	for (i = 0; i < mp->num_in; i++)
25961f28255Scgd 		mp->sq[i]->desc->monop = FALSE;
26061f28255Scgd 	mp->name = mp->not_m;
26161f28255Scgd }
262e42b2048Ssimonb 
26361f28255Scgd /*
26461f28255Scgd  *	This routine gives a list of the current player's routine
26561f28255Scgd  */
266b118ad22Schristos void
list(void)267*c34afa68Sdholland list(void)
268b118ad22Schristos {
26961f28255Scgd 	printhold(player);
27061f28255Scgd }
271e42b2048Ssimonb 
27261f28255Scgd /*
27361f28255Scgd  *	This routine gives a list of a given players holdings
27461f28255Scgd  */
275b118ad22Schristos void
list_all(void)276*c34afa68Sdholland list_all(void)
277b118ad22Schristos {
278b118ad22Schristos 	int pl;
27961f28255Scgd 
280e42b2048Ssimonb 	while ((pl = getinp("Whose holdings do you want to see? ", name_list))
281e42b2048Ssimonb 	    < num_play)
28261f28255Scgd 		printhold(pl);
28361f28255Scgd }
284e42b2048Ssimonb 
28561f28255Scgd /*
28661f28255Scgd  *	This routine gives the players a chance before it exits.
28761f28255Scgd  */
28861f28255Scgd void
quit(void)289*c34afa68Sdholland quit(void)
290b118ad22Schristos {
29161f28255Scgd 	putchar('\n');
292c509c631Sahoka 
293c509c631Sahoka 	/* We dont even have a chance to input y/n if stdin is closed */
294c509c631Sahoka 	if (feof(stdin))
295c509c631Sahoka 		exit(0);
296c509c631Sahoka 
297b118ad22Schristos 	if (getyn("Do you all really want to quit? ") == 0)
29861f28255Scgd 		exit(0);
29961f28255Scgd }
300