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