Annotation of 42BSD/games/fish.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.