1 /*        $NetBSD: misc.c,v 1.23 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 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)misc.c      8.1 (Berkeley) 5/31/93";
36 #else
37 __RCSID("$NetBSD: misc.c,v 1.23 2012/06/19 05:35:32 dholland Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #include <ctype.h>
42 #include <limits.h>
43 #include <signal.h>
44 #include <errno.h>
45 
46 #include "monop.h"
47 
48 static void is_monop(MON *, int);
49 
50 /*
51  *        This routine executes a truncated set of commands until a
52  * "yes or "no" answer is gotten.
53  */
54 int
getyn(const char * prompt)55 getyn(const char *prompt)
56 {
57           int com;
58 
59           for (;;)
60                     if ((com=getinp(prompt, yncoms)) < 2)
61                               return com;
62                     else
63                               (*func[com-2])();
64 }
65 
66 /*
67  *        This routine tells the player if he's out of money.
68  */
69 void
notify(void)70 notify(void)
71 {
72           if (cur_p->money < 0)
73                     printf("That leaves you $%d in debt\n", -cur_p->money);
74           else if (cur_p->money == 0)
75                     printf("that leaves you broke\n");
76           else if (fixing && !told_em && cur_p->money > 0) {
77                     printf("-- You are now Solvent ---\n");
78                     told_em = TRUE;
79           }
80 }
81 
82 /*
83  *        This routine switches to the next player
84  */
85 void
next_play(void)86 next_play(void)
87 {
88           player = (player + 1) % num_play;
89           cur_p = &play[player];
90           num_doub = 0;
91 }
92 
93 /*
94  *        This routine gets an integer from the keyboard after the
95  * given prompt.
96  */
97 int
get_int(const char * prompt)98 get_int(const char *prompt)
99 {
100           long num;
101           char *sp;
102           char buf[257];
103 
104           for (;;) {
105                     printf("%s", prompt);
106                     fgets(buf, sizeof(buf), stdin);
107                     /* if stdin is closed we cant really play anymore */
108                     if (feof(stdin))
109                               quit();
110                     sp = strchr(buf, '\n');
111                     if (sp)
112                               *sp = '\0';
113                     errno = 0;
114                     num = strtol(buf, &sp, 10);
115                     if (errno || strlen(sp) > 0 || num < 0 || num >= INT_MAX) {
116                               printf("I can't understand that\n");
117                               continue;
118                     }
119                     return num;
120           }
121 }
122 
123 /*
124  *        This routine sets the monopoly flag from the list given.
125  */
126 void
set_ownlist(int pl)127 set_ownlist(int pl)
128 {
129           int num;            /* general counter            */
130           MON *orig;                    /* remember starting monop ptr          */
131           OWN *op;            /* current owned prop                   */
132           OWN *orig_op;                 /* original prop before loop  */
133 
134           op = play[pl].own_list;
135 #ifdef DEBUG
136           printf("op [%p] = play[pl [%d] ].own_list;\n", op, pl);
137 #endif
138           while (op) {
139 #ifdef DEBUG
140                     printf("op->sqr->type = %d\n", op->sqr->type);
141 #endif
142                     switch (op->sqr->type) {
143                       case UTIL:
144 #ifdef DEBUG
145                               printf("  case UTIL:\n");
146 #endif
147                               for (num = 0; op && op->sqr->type == UTIL;
148                                   op = op->next)
149                                         num++;
150                               play[pl].num_util = num;
151 #ifdef DEBUG
152                               printf("play[pl].num_util = num [%d];\n", num);
153 #endif
154                               break;
155                       case RR:
156 #ifdef DEBUG
157                               printf("  case RR:\n");
158 #endif
159                               for (num = 0; op && op->sqr->type == RR;
160                                   op = op->next) {
161 #ifdef DEBUG
162                                         printf("iter: %d\n", num);
163                                         printf("op = %p, op->sqr = %p, "
164                                             "op->sqr->type = %d\n", op, op->sqr,
165                                             op->sqr->type);
166 #endif
167                                         num++;
168                               }
169                               play[pl].num_rr = num;
170 #ifdef DEBUG
171                               printf("play[pl].num_rr = num [%d];\n", num);
172 #endif
173                               break;
174                       case PRPTY:
175 #ifdef DEBUG
176                               printf("  case PRPTY:\n");
177 #endif
178                               orig = op->sqr->desc->mon_desc;
179                               orig_op = op;
180                               num = 0;
181                               while (op && op->sqr->desc->mon_desc == orig) {
182 #ifdef DEBUG
183                                         printf("iter: %d\n", num);
184 #endif
185                                         num++;
186 #ifdef DEBUG
187                                         printf("op = op->next ");
188 #endif
189                                         op = op->next;
190 #ifdef DEBUG
191                                         printf("[%p];\n", op);
192 #endif
193                               }
194 #ifdef DEBUG
195                               printf("num = %d\n", num);
196 #endif
197                               if (orig == NULL) {
198                                         printf("panic:  bad monopoly descriptor: "
199                                             "orig = %p\n", orig);
200                                         printf("player # %d\n", pl+1);
201                                         printhold(pl);
202                                         printf("orig_op = %p\n", orig_op);
203                                         if (orig_op) {
204                                                   printf("orig_op->sqr->type = %d (PRPTY)\n",
205                                                       orig_op->sqr->type);
206                                                   printf("orig_op->next = %p\n",
207                                                       orig_op->next);
208                                                   printf("orig_op->sqr->desc = %p\n",
209                                                       orig_op->sqr->desc);
210                                         }
211                                         printf("op = %p\n", op);
212                                         if (op) {
213                                                   printf("op->sqr->type = %d (PRPTY)\n",
214                                                       op->sqr->type);
215                                                   printf("op->next = %p\n", op->next);
216                                                   printf("op->sqr->desc = %p\n",
217                                                       op->sqr->desc);
218                                         }
219                                         printf("num = %d\n", num);
220                                         exit(1);
221                               }
222 #ifdef DEBUG
223                               printf("orig->num_in = %d\n", orig->num_in);
224 #endif
225                               if (num == orig->num_in)
226                                         is_monop(orig, pl);
227                               else
228                                         is_not_monop(orig);
229                               break;
230                     }
231           }
232 }
233 
234 /*
235  *        This routine sets things up as if it is a new monopoly
236  */
237 static void
is_monop(MON * mp,int pl)238 is_monop(MON *mp, int pl)
239 {
240           int i;
241 
242           mp->owner = pl;
243           mp->num_own = mp->num_in;
244           for (i = 0; i < mp->num_in; i++)
245                     mp->sq[i]->desc->monop = TRUE;
246           mp->name = mp->mon_n;
247 }
248 
249 /*
250  *        This routine sets things up as if it is no longer a monopoly
251  */
252 void
is_not_monop(MON * mp)253 is_not_monop(MON *mp)
254 {
255           int i;
256 
257           mp->owner = -1;
258           for (i = 0; i < mp->num_in; i++)
259                     mp->sq[i]->desc->monop = FALSE;
260           mp->name = mp->not_m;
261 }
262 
263 /*
264  *        This routine gives a list of the current player's routine
265  */
266 void
list(void)267 list(void)
268 {
269           printhold(player);
270 }
271 
272 /*
273  *        This routine gives a list of a given players holdings
274  */
275 void
list_all(void)276 list_all(void)
277 {
278           int pl;
279 
280           while ((pl = getinp("Whose holdings do you want to see? ", name_list))
281               < num_play)
282                     printhold(pl);
283 }
284 
285 /*
286  *        This routine gives the players a chance before it exits.
287  */
288 void
quit(void)289 quit(void)
290 {
291           putchar('\n');
292 
293           /* We dont even have a chance to input y/n if stdin is closed */
294           if (feof(stdin))
295                     exit(0);
296 
297           if (getyn("Do you all really want to quit? ") == 0)
298                     exit(0);
299 }
300