1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)fish.c	5.1 (Berkeley) 5/29/85";
  15: #endif not lint
  16: 
  17: # include <stdio.h>
  18: 
  19: /*	Through, `my' refers to the program, `your' to the player */
  20: 
  21: # define CTYPE 13
  22: # define CTSIZ (CTYPE+1)
  23: # define DECK 52
  24: # define NOMORE 0
  25: # define DOUBTIT (-1);
  26: 
  27: typedef char HAND[CTSIZ];
  28: 
  29: /* data structures */
  30: 
  31: short debug;
  32: 
  33: HAND myhand;
  34: HAND yourhand;
  35: char deck[DECK];
  36: short nextcd;
  37: int proflag;
  38: 
  39: /* utility and output programs */
  40: 
  41: shuffle(){
  42:     /* shuffle the deck, and reset nextcd */
  43:     /* uses the random number generator `rand' in the C library */
  44:     /* assumes that `srand' has already been called */
  45: 
  46:     register i;
  47: 
  48:     for( i=0; i<DECK; ++i ) deck[i] = (i%13)+1;  /* seed the deck */
  49: 
  50:     for( i=DECK; i>0; --i ){ /* select the next card at random */
  51:         deck[i-1] = choose( deck, i );
  52:         }
  53: 
  54:     nextcd = 0;
  55:     }
  56: 
  57: choose( a, n ) char a[]; {
  58:     /* pick and return one at random from the n choices in a */
  59:     /* The last one is moved to replace the one chosen */
  60:     register j, t;
  61: 
  62:     if( n <= 0 ) error( "null choice" );
  63: 
  64:     j = rand() % n;
  65:     t = a[j];
  66:     a[j] = a[n-1];
  67:     return(t);
  68:     }
  69: 
  70: draw() {
  71:     if( nextcd >= DECK ) return( NOMORE );
  72:     return( deck[nextcd++] );
  73:     }
  74: 
  75: error( s ) char *s; {
  76:     fprintf( stderr, "error: " );
  77:     fprintf( stderr, s );
  78:     exit( 1 );
  79:     }
  80: 
  81: empty( h ) HAND h; {
  82:     register i;
  83: 
  84:     for( i=1; i<=CTYPE; ++i ){
  85:         if( h[i] != 0 && h[i] != 4 ) return( 0 );
  86:         }
  87:     return( i );
  88:     }
  89: 
  90: mark( cd, hand ) HAND hand; {
  91:     if( cd != NOMORE ){
  92:         ++hand[cd];
  93:         if( hand[cd] > 4 ){
  94:             error( "mark overflow" );
  95:             }
  96:         }
  97:     return( cd );
  98:     }
  99: 
 100: deal( hand, n ) HAND hand; {
 101:     while( n-- ){
 102:         if( mark( hand, draw() ) == NOMORE ) error( "deck exhausted" );
 103:         }
 104:     }
 105: 
 106: char *cname[] = {
 107:     "NOMORE!!!",
 108:     "A",
 109:     "2",
 110:     "3",
 111:     "4",
 112:     "5",
 113:     "6",
 114:     "7",
 115:     "8",
 116:     "9",
 117:     "10",
 118:     "J",
 119:     "Q",
 120:     "K",
 121:     };
 122: 
 123: stats(){
 124:     register i, ct, b;
 125: 
 126:     if( proflag ) printf( "Pro level\n" );
 127:     b = ct = 0;
 128: 
 129:     for( i=1; i<=CTYPE; ++i ){
 130:         if( myhand[i] == 4 ) ++b;
 131:         else ct += myhand[i];
 132:         }
 133: 
 134:     if( b ){
 135:         printf( "My books: " );
 136:         for( i=1; i<=CTYPE; ++i ){
 137:             if( myhand[i] == 4 ) printf( "%s ", cname[i] );
 138:             }
 139:         printf( "\n" );
 140:         }
 141: 
 142:     printf( "%d cards in my hand, %d in the pool\n", ct, DECK-nextcd );
 143:     printf( "You ask me for: " );
 144:     }
 145: 
 146: phand( h ) HAND h; {
 147:     register i, j;
 148: 
 149:     j = 0;
 150: 
 151:     for( i = 1; i<= CTYPE; ++i ){
 152:         if( h[i] == 4 ) {
 153:             ++j;
 154:             continue;
 155:             }
 156:         if( h[i] ){
 157:             register k;
 158:             k = h[i];
 159:             while( k-- ) printf( "%s ", cname[i] );
 160:             }
 161:         }
 162: 
 163:     if( j ){
 164:         printf( "+ Books of " );
 165:         for( i=1; i<=CTYPE; ++i ){
 166:             if( h[i] == 4 ) printf( "%s ", cname[i] );
 167:             }
 168:         }
 169: 
 170:     printf( "\n" );
 171:     }
 172: 
 173: main( argc, argv ) char * argv[]; {
 174:     /* initialize shuffling, ask for instructions, play game, die */
 175:     register c;
 176: 
 177:     if( argc > 1 && argv[1][0] == '-' ){
 178:         while( argv[1][0] == '-' ) { ++argv[1]; ++debug; }
 179:         argv++;
 180:         argc--;
 181:         }
 182: 
 183:     srand( getpid() );
 184: 
 185:     printf( "instructions?\n" );
 186:     if( (c=getchar()) != '\n' ){
 187:         if( c != 'n' ) instruct();
 188:         while( getchar() != '\n' );
 189:         }
 190: 
 191:     game();
 192:     }
 193: 
 194: /*	print instructions */
 195: 
 196: char *inst[] = {
 197:     "`Go Fish' is a childrens' card game.  The Object is to",
 198:     "accumulate `books' of 4 cards with the same face value.  The",
 199:     "players alternate turns; each turn begins with one player",
 200:     "selecting a card from his hand, and asking the other player for",
 201:     "all cards of that face value.  If the other player has one or",
 202:     "more cards of that face value in his hand, he gives them to the",
 203:     "first player, and the first player makes another request.",
 204:     "Eventually, the first player asks for a card which is not in",
 205:     "the second player's hand: he replies `GO FISH!' The first",
 206:     "player then draws a card from the `pool' of undealt cards.  If",
 207:     "this is the card he had last requested, he draws again.  When a",
 208:     "book is made, either through drawing or requesting, the cards",
 209:     "are laid down and no further action takes place with that face",
 210:     "value.  To play the computer, simply make guesses by typing a,",
 211:     "2, 3, 4, 5, 6, 7, 8, 9, 10, j, q, or k when asked.  Hitting",
 212:     "return gives you information about the size of my hand and the",
 213:     "pool, and tells you about my books.  Saying `p' as a first",
 214:     "guess puts you into `pro' level; The default is pretty dumb!",
 215:     "Good Luck!\n",
 216:     "",
 217:     };
 218: 
 219: instruct(){
 220:     register char **cpp;
 221: 
 222:     printf( "\n" );
 223: 
 224:     for( cpp = inst; **cpp != '\0'; ++cpp ){
 225:         printf( "%s\n", *cpp );
 226:         }
 227:     }
 228: 
 229: game(){
 230: 
 231:     shuffle();
 232: 
 233:     deal( myhand, 7 );
 234:     deal( yourhand, 7 );
 235: 
 236:     start( myhand );
 237: 
 238:     for(;;){
 239: 
 240:         register g;
 241: 
 242: 
 243:         /* you make repeated guesses */
 244: 
 245:         for(;;) {
 246:             printf( "your hand is: " );
 247:             phand( yourhand );
 248:             printf( "you ask me for: " );
 249:             if( !move( yourhand, myhand, g=guess(), 0 ) ) break;
 250:             printf( "Guess again\n" );
 251:             }
 252: 
 253:         /* I make repeated guesses */
 254: 
 255:         for(;;) {
 256:             if( (g=myguess()) != NOMORE ){
 257:                 printf( "I ask you for: %s\n", cname[g] );
 258:                 }
 259:             if( !move( myhand, yourhand, g, 1 ) ) break;
 260:             printf( "I get another guess\n" );
 261:             }
 262:         }
 263:     }
 264: 
 265: /*	reflect the effect of a move on the hands */
 266: 
 267: move( hs, ht, g, v ) HAND hs, ht; {
 268:     /* hand hs has made a guess, g, directed towards ht */
 269:     /* v on indicates that the guess was made by the machine */
 270:     register d;
 271:     char *sp, *tp;
 272: 
 273:     sp = tp = "I";
 274:     if( v ) tp = "You";
 275:     else sp = "You";
 276: 
 277:     if( g == NOMORE ){
 278:         d = draw();
 279:         if( d == NOMORE ) score();
 280:         else {
 281: 
 282:             printf( "Empty Hand\n" );
 283:             if( !v ) printf( "You draw %s\n", cname[d] );
 284:             mark( hs, d );
 285:             }
 286:         return( 0 );
 287:         }
 288: 
 289:     if( !v ) heguessed( g );
 290: 
 291:     if( hs[g] == 0 ){
 292:         if( v ) error( "Rotten Guess" );
 293:         printf( "You don't have any %s's\n", cname[g] );
 294:         return(1);
 295:         }
 296: 
 297:     if( ht[g] ){ /* successful guess */
 298:         printf( "%s have %d %s%s\n", tp, ht[g], cname[g], ht[g]>1?"'s":"" );
 299:         hs[g] += ht[g];
 300:         ht[g] = 0;
 301:         if( hs[g] == 4 ) madebook(g);
 302:         return(1);
 303:         }
 304: 
 305:     /* GO FISH! */
 306: 
 307:     printf( "%s say \"GO FISH!\"\n", tp );
 308: 
 309:     newdraw:
 310:     d = draw();
 311:     if( d == NOMORE ) {
 312:         printf( "No more cards\n" );
 313:         return(0);
 314:         }
 315:     mark( hs, d );
 316:     if( !v ) printf( "You draw %s\n", cname[d] );
 317:     if( hs[d] == 4 ) madebook(d);
 318:     if( d == g ){
 319:         printf( "%s drew the guess, so draw again\n", sp );
 320:         if( !v ) hedrew( d );
 321:         goto newdraw;
 322:         }
 323:     return( 0 );
 324:     }
 325: 
 326: madebook( x ){
 327:     printf( "Made a book of %s's\n", cname[x] );
 328:     }
 329: 
 330: score(){
 331:     register my, your, i;
 332: 
 333:     my = your = 0;
 334: 
 335:     printf( "The game is over.\nMy books: " );
 336: 
 337:     for( i=1; i<=CTYPE;++i ){
 338:         if( myhand[i] == 4 ){
 339:             ++my;
 340:             printf( "%s ", cname[i] );
 341:             }
 342:         }
 343: 
 344:     printf( "\nYour books: " );
 345: 
 346:     for( i=1; i<=CTYPE;++i ){
 347:         if( yourhand[i] == 4 ){
 348:             ++your;
 349:             printf( "%s ", cname[i] );
 350:             }
 351:         }
 352: 
 353:     printf( "\n\nI have %d, you have %d\n", my, your );
 354: 
 355:     printf( "\n%s win!!!\n", my>your?"I":"You" );
 356:     exit(0);
 357:     }
 358: 
 359: # define G(x) { if(go) goto err;  else go = x; }
 360: 
 361: guess(){
 362:     /* get the guess from the tty and return it... */
 363:     register g, go;
 364: 
 365:     go = 0;
 366: 
 367:     for(;;) {
 368:         switch( g = getchar() ){
 369: 
 370:         case 'p':
 371:         case 'P':
 372:             ++proflag;
 373:             continue;
 374: 
 375:         case '2':
 376:         case '3':
 377:         case '4':
 378:         case '5':
 379:         case '6':
 380:         case '7':
 381:         case '8':
 382:         case '9':
 383:             G(g-'0');
 384:             continue;
 385: 
 386:         case 'a':
 387:         case 'A':
 388:             G(1);
 389:             continue;
 390: 
 391:         case '1':
 392:             G(10);
 393:             continue;
 394: 
 395:         case '0':
 396:             if( go != 10 ) goto err;
 397:             continue;
 398: 
 399:         case 'J':
 400:         case 'j':
 401:             G(11);
 402:             continue;
 403: 
 404:         case 'Q':
 405:         case 'q':
 406:             G(12);
 407:             continue;
 408: 
 409:         case 'K':
 410:         case 'k':
 411:             G(13);
 412:             continue;
 413: 
 414:         case '\n':
 415:             if( empty( yourhand ) ) return( NOMORE );
 416:             if( go == 0 ){
 417:                 stats();
 418:                 continue;
 419:                 }
 420:             return( go );
 421: 
 422:         case ' ':
 423:         case '\t':
 424:             continue;
 425: 
 426:         default:
 427:             err:
 428:             while( g != '\n' ) g = getchar();
 429:             printf( "what?\n" );
 430:             continue;
 431:             }
 432:         }
 433:     }
 434: 
 435: /*	the program's strategy appears from here to the end */
 436: 
 437: char try[100];
 438: char ntry;
 439: char haveguessed[CTSIZ];
 440: 
 441: char hehas[CTSIZ];
 442: 
 443: start( h ) HAND h; {
 444:     ;
 445:     }
 446: 
 447: hedrew( d ){
 448:     ++hehas[d];
 449:     }
 450: 
 451: heguessed( d ){
 452:     ++hehas[d];
 453:     }
 454: 
 455: myguess(){
 456: 
 457:     register i, lg, t;
 458: 
 459:     if( empty( myhand ) ) return( NOMORE );
 460: 
 461:     /* make a list of those things which i have */
 462:     /* leave off any which are books */
 463:     /* if something is found that he has, guess it! */
 464: 
 465:     ntry = 0;
 466:     for( i=1; i<=CTYPE; ++i ){
 467:         if( myhand[i] == 0 || myhand[i] == 4 ) continue;
 468:         try[ntry++] = i;
 469:         }
 470: 
 471:     if( !proflag ) goto random;
 472: 
 473:     /* get ones he has, if any */
 474: 
 475:     for( i=0; i<ntry; ++i ){
 476:         if( hehas[try[i]] ) {
 477:             i = try[i];
 478:             goto gotguess;
 479:             }
 480:         }
 481: 
 482:     /* is there one that has never been guessed; if so, guess it */
 483:     lg = 101;
 484:     for( i=0; i<ntry; ++i ){
 485:         if( haveguessed[try[i]] < lg ) lg = haveguessed[try[i]];
 486:         }
 487:     /* remove all those not guessed longest ago */
 488: 
 489:     t = 0;
 490:     for( i=0; i<ntry; ++i ){
 491:         if( haveguessed[try[i]] == lg ) try[t++] = try[i];
 492:         }
 493:     ntry = t;
 494:     if( t <= 0 ) error( "bad guessing loop" );
 495: 
 496:     random:
 497:     i = choose( try, ntry );  /* make a random choice */
 498: 
 499:     gotguess:  /* do bookkeeping */
 500: 
 501:     hehas[i] = 0;  /* he won't anymore! */
 502:     for( t=1; t<=CTYPE; ++t ){
 503:         if( haveguessed[t] ) --haveguessed[t];
 504:         }
 505:     haveguessed[i] = 100;  /* will have guessed it */
 506:     return(i);
 507: 
 508:     }

Defined functions

choose defined in line 57; used 2 times
deal defined in line 100; used 2 times
draw defined in line 70; used 3 times
empty defined in line 81; used 2 times
error defined in line 75; used 5 times
game defined in line 229; used 1 times
guess defined in line 361; used 1 times
hedrew defined in line 447; used 1 times
heguessed defined in line 451; used 1 times
instruct defined in line 219; used 1 times
madebook defined in line 326; used 2 times
main defined in line 173; never used
mark defined in line 90; used 3 times
move defined in line 267; used 2 times
myguess defined in line 455; used 1 times
phand defined in line 146; used 1 times
score defined in line 330; used 1 times
shuffle defined in line 41; used 1 times
start defined in line 443; used 1 times
stats defined in line 123; used 1 times

Defined variables

cname defined in line 106; used 11 times
copyright defined in line 8; never used
debug defined in line 31; used 1 times
deck defined in line 35; used 4 times
haveguessed defined in line 439; used 6 times
hehas defined in line 441; used 4 times
inst defined in line 196; used 1 times
myhand defined in line 33; used 11 times
nextcd defined in line 36; used 4 times
ntry defined in line 438; used 7 times
proflag defined in line 37; used 3 times
sccsid defined in line 14; never used
try defined in line 437; used 9 times
yourhand defined in line 34; used 6 times

Defined typedef's

HAND defined in line 27; used 8 times

Defined macros

CTSIZ defined in line 22; used 3 times
CTYPE defined in line 21; used 10 times
DECK defined in line 23; used 5 times
DOUBTIT defined in line 25; never used
G defined in line 359; used 6 times
NOMORE defined in line 24; used 9 times
Last modified: 1985-05-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4317
Valid CSS Valid XHTML 1.0 Strict