1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Muffy Barkocy. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #ifndef lint 38 char copyright[] = 39 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 40 All rights reserved.\n"; 41 #endif /* not lint */ 42 43 #ifndef lint 44 /*static char sccsid[] = "from: @(#)fish.c 5.4 (Berkeley) 1/18/91";*/ 45 static char rcsid[] = "$Id: fish.c,v 1.2 1993/08/01 18:54:54 mycroft Exp $"; 46 #endif /* not lint */ 47 48 #include <sys/types.h> 49 #include <sys/errno.h> 50 #include <fcntl.h> 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <string.h> 54 #include "pathnames.h" 55 56 #define RANKS 13 57 #define HANDSIZE 7 58 #define CARDS 4 59 60 #define USER 1 61 #define COMPUTER 0 62 #define OTHER(a) (1 - (a)) 63 64 char *cards[] = { 65 "A", "2", "3", "4", "5", "6", "7", 66 "8", "9", "10", "J", "Q", "K", NULL, 67 }; 68 #define PRC(card) (void)printf(" %s", cards[card]) 69 70 int promode; 71 int asked[RANKS], comphand[RANKS], deck[RANKS]; 72 int userasked[RANKS], userhand[RANKS]; 73 74 main(argc, argv) 75 int argc; 76 char **argv; 77 { 78 int ch, move; 79 80 while ((ch = getopt(argc, argv, "p")) != EOF) 81 switch(ch) { 82 case 'p': 83 promode = 1; 84 break; 85 case '?': 86 default: 87 (void)fprintf(stderr, "usage: fish [-p]\n"); 88 exit(1); 89 } 90 91 srandom(time((time_t *)NULL)); 92 instructions(); 93 init(); 94 95 if (nrandom(2) == 1) { 96 printplayer(COMPUTER); 97 (void)printf("get to start.\n"); 98 goto istart; 99 } 100 printplayer(USER); 101 (void)printf("get to start.\n"); 102 103 for (;;) { 104 move = usermove(); 105 if (!comphand[move]) { 106 if (gofish(move, USER, userhand)) 107 continue; 108 } else { 109 goodmove(USER, move, userhand, comphand); 110 continue; 111 } 112 113 istart: for (;;) { 114 move = compmove(); 115 if (!userhand[move]) { 116 if (!gofish(move, COMPUTER, comphand)) 117 break; 118 } else 119 goodmove(COMPUTER, move, comphand, userhand); 120 } 121 } 122 /* NOTREACHED */ 123 } 124 125 usermove() 126 { 127 register int n; 128 register char **p; 129 char buf[256]; 130 131 (void)printf("\nYour hand is:"); 132 printhand(userhand); 133 134 for (;;) { 135 (void)printf("You ask me for: "); 136 (void)fflush(stdout); 137 if (fgets(buf, BUFSIZ, stdin) == NULL) 138 exit(0); 139 if (buf[0] == '\0') 140 continue; 141 if (buf[0] == '\n') { 142 (void)printf("%d cards in my hand, %d in the pool.\n", 143 countcards(comphand), countcards(deck)); 144 (void)printf("My books:"); 145 (void)countbooks(comphand); 146 continue; 147 } 148 buf[strlen(buf) - 1] = '\0'; 149 if (!strcasecmp(buf, "p") && !promode) { 150 promode = 1; 151 (void)printf("Entering pro mode.\n"); 152 continue; 153 } 154 if (!strcasecmp(buf, "quit")) 155 exit(0); 156 for (p = cards; *p; ++p) 157 if (!strcasecmp(*p, buf)) 158 break; 159 if (!*p) { 160 (void)printf("I don't understand!\n"); 161 continue; 162 } 163 n = p - cards; 164 if (userhand[n]) { 165 userasked[n] = 1; 166 return(n); 167 } 168 if (nrandom(3) == 1) 169 (void)printf("You don't have any of those!\n"); 170 else 171 (void)printf("You don't have any %s's!\n", cards[n]); 172 if (nrandom(4) == 1) 173 (void)printf("No cheating!\n"); 174 (void)printf("Guess again.\n"); 175 } 176 /* NOTREACHED */ 177 } 178 179 compmove() 180 { 181 static int lmove; 182 183 if (promode) 184 lmove = promove(); 185 else { 186 do { 187 lmove = (lmove + 1) % RANKS; 188 } while (!comphand[lmove] || comphand[lmove] == CARDS); 189 } 190 asked[lmove] = 1; 191 192 (void)printf("I ask you for: %s.\n", cards[lmove]); 193 return(lmove); 194 } 195 196 promove() 197 { 198 register int i, max; 199 200 for (i = 0; i < RANKS; ++i) 201 if (userasked[i] && 202 comphand[i] > 0 && comphand[i] < CARDS) { 203 userasked[i] = 0; 204 return(i); 205 } 206 if (nrandom(3) == 1) { 207 for (i = 0;; ++i) 208 if (comphand[i] && comphand[i] != CARDS) { 209 max = i; 210 break; 211 } 212 while (++i < RANKS) 213 if (comphand[i] != CARDS && 214 comphand[i] > comphand[max]) 215 max = i; 216 return(max); 217 } 218 if (nrandom(1024) == 0723) { 219 for (i = 0; i < RANKS; ++i) 220 if (userhand[i] && comphand[i]) 221 return(i); 222 } 223 for (;;) { 224 for (i = 0; i < RANKS; ++i) 225 if (comphand[i] && comphand[i] != CARDS && 226 !asked[i]) 227 return(i); 228 for (i = 0; i < RANKS; ++i) 229 asked[i] = 0; 230 } 231 /* NOTREACHED */ 232 } 233 234 drawcard(player, hand) 235 int player; 236 int *hand; 237 { 238 int card; 239 240 while (deck[card = nrandom(RANKS)] == 0); 241 ++hand[card]; 242 --deck[card]; 243 if (player == USER || hand[card] == CARDS) { 244 printplayer(player); 245 (void)printf("drew %s", cards[card]); 246 if (hand[card] == CARDS) { 247 (void)printf(" and made a book of %s's!\n", 248 cards[card]); 249 chkwinner(player, hand); 250 } else 251 (void)printf(".\n"); 252 } 253 return(card); 254 } 255 256 gofish(askedfor, player, hand) 257 int askedfor, player; 258 int *hand; 259 { 260 printplayer(OTHER(player)); 261 (void)printf("say \"GO FISH!\"\n"); 262 if (askedfor == drawcard(player, hand)) { 263 printplayer(player); 264 (void)printf("drew the guess!\n"); 265 printplayer(player); 266 (void)printf("get to ask again!\n"); 267 return(1); 268 } 269 return(0); 270 } 271 272 goodmove(player, move, hand, opphand) 273 int player, move; 274 int *hand, *opphand; 275 { 276 printplayer(OTHER(player)); 277 (void)printf("have %d %s%s.\n", 278 opphand[move], cards[move], opphand[move] == 1 ? "": "'s"); 279 280 hand[move] += opphand[move]; 281 opphand[move] = 0; 282 283 if (hand[move] == CARDS) { 284 printplayer(player); 285 (void)printf("made a book of %s's!\n", cards[move]); 286 chkwinner(player, hand); 287 } 288 289 chkwinner(OTHER(player), opphand); 290 291 printplayer(player); 292 (void)printf("get another guess!\n"); 293 } 294 295 chkwinner(player, hand) 296 int player; 297 register int *hand; 298 { 299 register int cb, i, ub; 300 301 for (i = 0; i < RANKS; ++i) 302 if (hand[i] > 0 && hand[i] < CARDS) 303 return; 304 printplayer(player); 305 (void)printf("don't have any more cards!\n"); 306 (void)printf("My books:"); 307 cb = countbooks(comphand); 308 (void)printf("Your books:"); 309 ub = countbooks(userhand); 310 (void)printf("\nI have %d, you have %d.\n", cb, ub); 311 if (ub > cb) { 312 (void)printf("\nYou win!!!\n"); 313 if (nrandom(1024) == 0723) 314 (void)printf("Cheater, cheater, pumpkin eater!\n"); 315 } else if (cb > ub) { 316 (void)printf("\nI win!!!\n"); 317 if (nrandom(1024) == 0723) 318 (void)printf("Hah! Stupid peasant!\n"); 319 } else 320 (void)printf("\nTie!\n"); 321 exit(0); 322 } 323 324 printplayer(player) 325 int player; 326 { 327 switch (player) { 328 case COMPUTER: 329 (void)printf("I "); 330 break; 331 case USER: 332 (void)printf("You "); 333 break; 334 } 335 } 336 337 printhand(hand) 338 int *hand; 339 { 340 register int book, i, j; 341 342 for (book = i = 0; i < RANKS; i++) 343 if (hand[i] < CARDS) 344 for (j = hand[i]; --j >= 0;) 345 PRC(i); 346 else 347 ++book; 348 if (book) { 349 (void)printf(" + Book%s of", book > 1 ? "s" : ""); 350 for (i = 0; i < RANKS; i++) 351 if (hand[i] == CARDS) 352 PRC(i); 353 } 354 (void)putchar('\n'); 355 } 356 357 countcards(hand) 358 register int *hand; 359 { 360 register int i, count; 361 362 for (count = i = 0; i < RANKS; i++) 363 count += *hand++; 364 return(count); 365 } 366 367 countbooks(hand) 368 int *hand; 369 { 370 int i, count; 371 372 for (count = i = 0; i < RANKS; i++) 373 if (hand[i] == CARDS) { 374 ++count; 375 PRC(i); 376 } 377 if (!count) 378 (void)printf(" none"); 379 (void)putchar('\n'); 380 return(count); 381 } 382 383 init() 384 { 385 register int i, rank; 386 387 for (i = 0; i < RANKS; ++i) 388 deck[i] = CARDS; 389 for (i = 0; i < HANDSIZE; ++i) { 390 while (!deck[rank = nrandom(RANKS)]); 391 ++userhand[rank]; 392 --deck[rank]; 393 } 394 for (i = 0; i < HANDSIZE; ++i) { 395 while (!deck[rank = nrandom(RANKS)]); 396 ++comphand[rank]; 397 --deck[rank]; 398 } 399 } 400 401 nrandom(n) 402 int n; 403 { 404 long random(); 405 406 return((int)random() % n); 407 } 408 409 instructions() 410 { 411 int input; 412 char buf[1024]; 413 414 (void)printf("Would you like instructions (y or n)? "); 415 input = getchar(); 416 while (getchar() != '\n'); 417 if (input != 'y') 418 return; 419 420 (void)sprintf(buf, "%s %s", _PATH_MORE, _PATH_INSTR); 421 (void)system(buf); 422 (void)printf("Hit return to continue...\n"); 423 while ((input = getchar()) != EOF && input != '\n'); 424 } 425 426 usage() 427 { 428 (void)fprintf(stderr, "usage: fish [-p]\n"); 429 exit(1); 430 } 431