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

Defined functions

choose defined in line 41; used 2 times
deal defined in line 84; used 2 times
draw defined in line 54; used 3 times
empty defined in line 65; used 2 times
error defined in line 59; used 5 times
game defined in line 218; used 1 times
guess defined in line 350; used 1 times
hedrew defined in line 436; used 1 times
heguessed defined in line 440; used 1 times
instruct defined in line 208; used 1 times
madebook defined in line 315; used 2 times
main defined in line 157; never used
mark defined in line 74; used 3 times
move defined in line 256; used 2 times
myguess defined in line 444; used 1 times
phand defined in line 130; used 1 times
score defined in line 319; used 1 times
shuffle defined in line 25; used 1 times
start defined in line 432; used 1 times
stats defined in line 107; used 1 times

Defined variables

cname defined in line 90; used 11 times
debug defined in line 15; used 1 times
deck defined in line 19; used 4 times
haveguessed defined in line 428; used 6 times
hehas defined in line 430; used 4 times
inst defined in line 180; used 1 times
myhand defined in line 17; used 11 times
nextcd defined in line 20; used 4 times
ntry defined in line 427; used 7 times
proflag defined in line 21; used 3 times
try defined in line 426; used 9 times
yourhand defined in line 18; used 6 times

Defined typedef's

HAND defined in line 11; used 8 times

Defined macros

CTSIZ defined in line 6; used 3 times
CTYPE defined in line 5; used 10 times
DECK defined in line 7; used 5 times
DOUBTIT defined in line 9; never used
G defined in line 348; used 6 times
NOMORE defined in line 8; used 9 times
Last modified: 1979-01-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1150
Valid CSS Valid XHTML 1.0 Strict