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 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 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 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 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 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 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 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 267 list(void) 268 { 269 printhold(player); 270 } 271 272 /* 273 * This routine gives a list of a given players holdings 274 */ 275 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 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