Annotation of 43BSD/games/cribbage/crib.c, revision 1.1

1.1     ! root        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[] = "@(#)crib.c     5.1 (Berkeley) 5/30/85";
        !            15: #endif not lint
        !            16: 
        !            17: # include      <curses.h>
        !            18: # include      <signal.h>
        !            19: # include      "deck.h"
        !            20: # include      "cribbage.h"
        !            21: # include      "cribcur.h"
        !            22: 
        !            23: 
        !            24: # define       LOGFILE         "/usr/games/lib/criblog"
        !            25: # define       INSTRCMD        "ul /usr/games/lib/crib.instr | more -f"
        !            26: 
        !            27: 
        !            28: main(argc, argv)
        !            29: int    argc;
        !            30: char   *argv[];
        !            31: {
        !            32:        register  char          *p;
        !            33:        BOOLEAN                 playing;
        !            34:        char                    *s;             /* for reading arguments */
        !            35:        char                    bust;           /* flag for arg reader */
        !            36:        FILE                    *f;
        !            37:        FILE                    *fopen();
        !            38:        char                    *getline();
        !            39:        int                     bye();
        !            40: 
        !            41:        while (--argc > 0) {
        !            42:            if ((*++argv)[0] != '-') {
        !            43:                fprintf(stderr, "\n\ncribbage: usage is 'cribbage [-eqr]'\n");
        !            44:                exit(1);
        !            45:            }
        !            46:            bust = FALSE;
        !            47:            for (s = argv[0] + 1; *s != NULL; s++) {
        !            48:                switch (*s) {
        !            49:                    case 'e':
        !            50:                        explain = TRUE;
        !            51:                        break;
        !            52:                    case 'q':
        !            53:                        quiet = TRUE;
        !            54:                        break;
        !            55:                    case 'r':
        !            56:                        rflag = TRUE;
        !            57:                        break;
        !            58:                    default:
        !            59:                        fprintf(stderr, "\n\ncribbage: usage is 'cribbage [-eqr]'\n");
        !            60:                        exit(2);
        !            61:                        break;
        !            62:                }
        !            63:                if (bust)
        !            64:                    break;
        !            65:            }
        !            66:        }
        !            67: 
        !            68:        initscr();
        !            69:        signal(SIGINT, bye);
        !            70:        crmode();
        !            71:        noecho();
        !            72:        Playwin = subwin(stdscr, PLAY_Y, PLAY_X, 0, 0);
        !            73:        Tablewin = subwin(stdscr, TABLE_Y, TABLE_X, 0, PLAY_X);
        !            74:        Compwin = subwin(stdscr, COMP_Y, COMP_X, 0, TABLE_X + PLAY_X);
        !            75:        Msgwin = subwin(stdscr, MSG_Y, MSG_X, Y_MSG_START, SCORE_X + 1);
        !            76:        leaveok(Playwin, TRUE);
        !            77:        leaveok(Tablewin, TRUE);
        !            78:        leaveok(Compwin, TRUE);
        !            79:        clearok(stdscr, FALSE);
        !            80: 
        !            81:        if (!quiet) {
        !            82:            msg("Do you need instructions for cribbage? ");
        !            83:            if (getuchar() == 'Y') {
        !            84:                endwin();
        !            85:                fflush(stdout);
        !            86:                system(INSTRCMD);
        !            87:                crmode();
        !            88:                noecho();
        !            89:                clear();
        !            90:                refresh();
        !            91:                msg("For the rules of this program, do \"man cribbage\"");
        !            92:            }
        !            93:        }
        !            94:        playing = TRUE;
        !            95:        do {
        !            96:            wclrtobot(Msgwin);
        !            97:            msg(quiet ? "L or S? " : "Long (to 121) or Short (to 61)? ");
        !            98:            if (glimit == SGAME)
        !            99:                glimit = (getuchar() == 'L' ? LGAME : SGAME);
        !           100:            else
        !           101:                glimit = (getuchar() == 'S' ? SGAME : LGAME);
        !           102:            game();
        !           103:            msg("Another game? ");
        !           104:            playing = (getuchar() == 'Y');
        !           105:        } while (playing);
        !           106: 
        !           107:        if ((f = fopen(LOGFILE, "a")) != NULL) {
        !           108:            fprintf(f, "Won %5.5d, Lost %5.5d\n",  cgames, pgames);
        !           109:            fclose(f);
        !           110:        }
        !           111: 
        !           112:        bye();
        !           113: }
        !           114: 
        !           115: /*
        !           116:  * makeboard:
        !           117:  *     Print out the initial board on the screen
        !           118:  */
        !           119: makeboard()
        !           120: {
        !           121:     mvaddstr(SCORE_Y + 0, SCORE_X, "+---------------------------------------+");
        !           122:     mvaddstr(SCORE_Y + 1, SCORE_X, "|  Score:   0     YOU                   |");
        !           123:     mvaddstr(SCORE_Y + 2, SCORE_X, "| *.....:.....:.....:.....:.....:.....  |");
        !           124:     mvaddstr(SCORE_Y + 3, SCORE_X, "| *.....:.....:.....:.....:.....:.....  |");
        !           125:     mvaddstr(SCORE_Y + 4, SCORE_X, "|                                       |");
        !           126:     mvaddstr(SCORE_Y + 5, SCORE_X, "| *.....:.....:.....:.....:.....:.....  |");
        !           127:     mvaddstr(SCORE_Y + 6, SCORE_X, "| *.....:.....:.....:.....:.....:.....  |");
        !           128:     mvaddstr(SCORE_Y + 7, SCORE_X, "|  Score:   0      ME                   |");
        !           129:     mvaddstr(SCORE_Y + 8, SCORE_X, "+---------------------------------------+");
        !           130:     gamescore();
        !           131: }
        !           132: 
        !           133: /*
        !           134:  * gamescore:
        !           135:  *     Print out the current game score
        !           136:  */
        !           137: gamescore()
        !           138: {
        !           139:     extern int Lastscore[];
        !           140: 
        !           141:     if (pgames || cgames) {
        !           142:            mvprintw(SCORE_Y + 1, SCORE_X + 28, "Games: %3d", pgames);
        !           143:            mvprintw(SCORE_Y + 7, SCORE_X + 28, "Games: %3d", cgames);
        !           144:     }
        !           145:     Lastscore[0] = -1;
        !           146:     Lastscore[1] = -1;
        !           147: }
        !           148: 
        !           149: /*
        !           150:  * game:
        !           151:  *     Play one game up to glimit points.  Actually, we only ASK the
        !           152:  *     player what card to turn.  We do a random one, anyway.
        !           153:  */
        !           154: game()
        !           155: {
        !           156:        register int            i, j;
        !           157:        BOOLEAN                 flag;
        !           158:        BOOLEAN                 compcrib;
        !           159: 
        !           160:        makeboard();
        !           161:        refresh();
        !           162:        makedeck(deck);
        !           163:        shuffle(deck);
        !           164:        if (gamecount == 0) {
        !           165:            flag = TRUE;
        !           166:            do {
        !           167:                if (!rflag) {                           /* player cuts deck */
        !           168:                    msg(quiet ? "Cut for crib? " :
        !           169:                        "Cut to see whose crib it is -- low card wins? ");
        !           170:                    getline();
        !           171:                }
        !           172:                i = (rand() >> 4) % CARDS;              /* random cut */
        !           173:                do {                                    /* comp cuts deck */
        !           174:                    j = (rand() >> 4) % CARDS;
        !           175:                } while (j == i);
        !           176:                addmsg(quiet ? "You cut " : "You cut the ");
        !           177:                msgcard(deck[i], FALSE);
        !           178:                endmsg();
        !           179:                addmsg(quiet ? "I cut " : "I cut the ");
        !           180:                msgcard(deck[j], FALSE);
        !           181:                endmsg();
        !           182:                flag = (deck[i].rank == deck[j].rank);
        !           183:                if (flag) {
        !           184:                    msg(quiet ? "We tied..." :
        !           185:                        "We tied and have to try again...");
        !           186:                    shuffle(deck);
        !           187:                    continue;
        !           188:                }
        !           189:                else
        !           190:                    compcrib = (deck[i].rank > deck[j].rank);
        !           191:            } while (flag);
        !           192:        }
        !           193:        else {
        !           194:            werase(Tablewin);
        !           195:            wrefresh(Tablewin);
        !           196:            werase(Compwin);
        !           197:            wrefresh(Compwin);
        !           198:            msg("Loser (%s) gets first crib",  (iwon ? "you" : "me"));
        !           199:            compcrib = !iwon;
        !           200:        }
        !           201: 
        !           202:        pscore = cscore = 0;
        !           203:        flag = TRUE;
        !           204:        do {
        !           205:            shuffle(deck);
        !           206:            flag = !playhand(compcrib);
        !           207:            compcrib = !compcrib;
        !           208:        } while (flag);
        !           209:        ++gamecount;
        !           210:        if (cscore < pscore) {
        !           211:            if (glimit - cscore > 60) {
        !           212:                msg("YOU DOUBLE SKUNKED ME!");
        !           213:                pgames += 4;
        !           214:            }
        !           215:            else if (glimit - cscore > 30) {
        !           216:                msg("YOU SKUNKED ME!");
        !           217:                pgames += 2;
        !           218:            }
        !           219:            else {
        !           220:                msg("YOU WON!");
        !           221:                ++pgames;
        !           222:            }
        !           223:            iwon = FALSE;
        !           224:        }
        !           225:        else {
        !           226:            if (glimit - pscore > 60) {
        !           227:                msg("I DOUBLE SKUNKED YOU!");
        !           228:                cgames += 4;
        !           229:            }
        !           230:            else if (glimit - pscore > 30) {
        !           231:                msg("I SKUNKED YOU!");
        !           232:                cgames += 2;
        !           233:            }
        !           234:            else {
        !           235:                msg("I WON!");
        !           236:                ++cgames;
        !           237:            }
        !           238:            iwon = TRUE;
        !           239:        }
        !           240:        gamescore();
        !           241: }
        !           242: 
        !           243: /*
        !           244:  * playhand:
        !           245:  *     Do up one hand of the game
        !           246:  */
        !           247: playhand(mycrib)
        !           248: BOOLEAN                mycrib;
        !           249: {
        !           250:        register int            deckpos;
        !           251:        extern char             Msgbuf[];
        !           252: 
        !           253:        werase(Compwin);
        !           254: 
        !           255:        knownum = 0;
        !           256:        deckpos = deal(mycrib);
        !           257:        sorthand(chand, FULLHAND);
        !           258:        sorthand(phand, FULLHAND);
        !           259:        makeknown(chand, FULLHAND);
        !           260:        prhand(phand, FULLHAND, Playwin, FALSE);
        !           261:        discard(mycrib);
        !           262:        if (cut(mycrib, deckpos))
        !           263:            return TRUE;
        !           264:        if (peg(mycrib))
        !           265:            return TRUE;
        !           266:        werase(Tablewin);
        !           267:        wrefresh(Tablewin);
        !           268:        if (score(mycrib))
        !           269:            return TRUE;
        !           270:        return FALSE;
        !           271: }
        !           272: 
        !           273: 
        !           274: 
        !           275: /*
        !           276:  * deal cards to both players from deck
        !           277:  */
        !           278: 
        !           279: deal( mycrib )
        !           280: {
        !           281:        register  int           i, j;
        !           282: 
        !           283:        j = 0;
        !           284:        for( i = 0; i < FULLHAND; i++ )  {
        !           285:            if( mycrib )  {
        !           286:                phand[i] = deck[j++];
        !           287:                chand[i] = deck[j++];
        !           288:            }
        !           289:            else  {
        !           290:                chand[i] = deck[j++];
        !           291:                phand[i] = deck[j++];
        !           292:            }
        !           293:        }
        !           294:        return( j );
        !           295: }
        !           296: 
        !           297: /*
        !           298:  * discard:
        !           299:  *     Handle players discarding into the crib...
        !           300:  * Note: we call cdiscard() after prining first message so player doesn't wait
        !           301:  */
        !           302: discard(mycrib)
        !           303: BOOLEAN                mycrib;
        !           304: {
        !           305:        register char   *prompt;
        !           306:        CARD            crd;
        !           307: 
        !           308:        prcrib(mycrib, TRUE);
        !           309:        prompt = (quiet ? "Discard --> " : "Discard a card --> ");
        !           310:        cdiscard(mycrib);                       /* puts best discard at end */
        !           311:        crd = phand[infrom(phand, FULLHAND, prompt)];
        !           312:        remove(crd, phand, FULLHAND);
        !           313:        prhand(phand, FULLHAND, Playwin, FALSE);
        !           314:        crib[0] = crd;
        !           315: /* next four lines same as last four except for cdiscard() */
        !           316:        crd = phand[infrom(phand, FULLHAND - 1, prompt)];
        !           317:        remove(crd, phand, FULLHAND - 1);
        !           318:        prhand(phand, FULLHAND, Playwin, FALSE);
        !           319:        crib[1] = crd;
        !           320:        crib[2] = chand[4];
        !           321:        crib[3] = chand[5];
        !           322:        chand[4].rank = chand[4].suit = chand[5].rank = chand[5].suit = EMPTY;
        !           323: }
        !           324: 
        !           325: /*
        !           326:  * cut:
        !           327:  *     Cut the deck and set turnover.  Actually, we only ASK the
        !           328:  *     player what card to turn.  We do a random one, anyway.
        !           329:  */
        !           330: cut(mycrib, pos)
        !           331: BOOLEAN                mycrib;
        !           332: int            pos;
        !           333: {
        !           334:        register int            i, cardx;
        !           335:        BOOLEAN                 win = FALSE;
        !           336: 
        !           337:        if (mycrib) {
        !           338:            if (!rflag) {                       /* random cut */
        !           339:                msg(quiet ? "Cut the deck? " :
        !           340:                        "How many cards down do you wish to cut the deck? ");
        !           341:                getline();
        !           342:            }
        !           343:            i = (rand() >> 4) % (CARDS - pos);
        !           344:            turnover = deck[i + pos];
        !           345:            addmsg(quiet ? "You cut " : "You cut the ");
        !           346:            msgcard(turnover, FALSE);
        !           347:            endmsg();
        !           348:            if (turnover.rank == JACK) {
        !           349:                msg("I get two for his heels");
        !           350:                win = chkscr(&cscore,2 );
        !           351:            }
        !           352:        }
        !           353:        else {
        !           354:            i = (rand() >> 4) % (CARDS - pos) + pos;
        !           355:            turnover = deck[i];
        !           356:            addmsg(quiet ? "I cut " : "I cut the ");
        !           357:            msgcard(turnover, FALSE);
        !           358:            endmsg();
        !           359:            if (turnover.rank == JACK) {
        !           360:                msg("You get two for his heels");
        !           361:                win = chkscr(&pscore, 2);
        !           362:            }
        !           363:        }
        !           364:        makeknown(&turnover, 1);
        !           365:        prcrib(mycrib, FALSE);
        !           366:        return win;
        !           367: }
        !           368: 
        !           369: /*
        !           370:  * prcrib:
        !           371:  *     Print out the turnover card with crib indicator
        !           372:  */
        !           373: prcrib(mycrib, blank)
        !           374: BOOLEAN                mycrib, blank;
        !           375: {
        !           376:        register int    y, cardx;
        !           377: 
        !           378:        if (mycrib)
        !           379:            cardx = CRIB_X;
        !           380:        else
        !           381:            cardx = 0;
        !           382: 
        !           383:        mvaddstr(CRIB_Y, cardx + 1, "CRIB");
        !           384:        prcard(stdscr, CRIB_Y + 1, cardx, turnover, blank);
        !           385: 
        !           386:        if (mycrib)
        !           387:            cardx = 0;
        !           388:        else
        !           389:            cardx = CRIB_X;
        !           390: 
        !           391:        for (y = CRIB_Y; y <= CRIB_Y + 5; y++)
        !           392:            mvaddstr(y, cardx, "       ");
        !           393: }
        !           394: 
        !           395: /*
        !           396:  * peg:
        !           397:  *     Handle all the pegging...
        !           398:  */
        !           399: 
        !           400: static CARD            Table[14];
        !           401: 
        !           402: static int             Tcnt;
        !           403: 
        !           404: peg(mycrib)
        !           405: BOOLEAN                mycrib;
        !           406: {
        !           407:        static CARD             ch[CINHAND], ph[CINHAND];
        !           408:        CARD                    crd;
        !           409:        register int            i, j, k;
        !           410:        register int            l;
        !           411:        register int            cnum, pnum, sum;
        !           412:        register BOOLEAN        myturn, mego, ugo, last, played;
        !           413: 
        !           414:        cnum = pnum = CINHAND;
        !           415:        for (i = 0; i < CINHAND; i++) {         /* make copies of hands */
        !           416:            ch[i] = chand[i];
        !           417:            ph[i] = phand[i];
        !           418:        }
        !           419:        Tcnt = 0;                       /* index to table of cards played */
        !           420:        sum = 0;                        /* sum of cards played */
        !           421:        mego = ugo = FALSE;
        !           422:        myturn = !mycrib;
        !           423:        for (;;) {
        !           424:            last = TRUE;                                /* enable last flag */
        !           425:            prhand(ph, pnum, Playwin, FALSE);
        !           426:            prhand(ch, cnum, Compwin, TRUE);
        !           427:            prtable(sum);
        !           428:            if (myturn) {                               /* my tyrn to play */
        !           429:                if (!anymove(ch, cnum, sum)) {          /* if no card to play */
        !           430:                    if (!mego && cnum) {                /* go for comp? */
        !           431:                        msg("GO");
        !           432:                        mego = TRUE;
        !           433:                    }
        !           434:                    if (anymove(ph, pnum, sum))         /* can player move? */
        !           435:                        myturn = !myturn;
        !           436:                    else {                              /* give him his point */
        !           437:                        msg(quiet ? "You get one" : "You get one point");
        !           438:                        if (chkscr(&pscore, 1))
        !           439:                            return TRUE;
        !           440:                        sum = 0;
        !           441:                        mego = ugo = FALSE;
        !           442:                        Tcnt = 0;
        !           443:                    }
        !           444:                }
        !           445:                else {
        !           446:                    played = TRUE;
        !           447:                    j = -1;
        !           448:                    k = 0;
        !           449:                    for (i = 0; i < cnum; i++) {        /* maximize score */
        !           450:                        l = pegscore(ch[i], Table, Tcnt, sum);
        !           451:                        if (l > k) {
        !           452:                            k = l;
        !           453:                            j = i;
        !           454:                        }
        !           455:                    }
        !           456:                    if (j < 0)                          /* if nothing scores */
        !           457:                        j = cchose(ch, cnum, sum);
        !           458:                    crd = ch[j];
        !           459:                    remove(crd, ch, cnum--);
        !           460:                    sum += VAL(crd.rank);
        !           461:                    Table[Tcnt++] = crd;
        !           462:                    if (k > 0) {
        !           463:                        addmsg(quiet ? "I get %d playing " :
        !           464:                            "I get %d points playing ", k);
        !           465:                        msgcard(crd, FALSE);
        !           466:                        endmsg();
        !           467:                        if (chkscr(&cscore, k))
        !           468:                            return TRUE;
        !           469:                    }
        !           470:                    myturn = !myturn;
        !           471:                }
        !           472:            }
        !           473:            else {
        !           474:                if (!anymove(ph, pnum, sum)) {          /* can player move? */
        !           475:                    if (!ugo && pnum) {                 /* go for player */
        !           476:                        msg("You have a GO");
        !           477:                        ugo = TRUE;
        !           478:                    }
        !           479:                    if (anymove(ch, cnum, sum))         /* can computer play? */
        !           480:                        myturn = !myturn;
        !           481:                    else {
        !           482:                        msg(quiet ? "I get one" : "I get one point");
        !           483:                        do_wait();
        !           484:                        if (chkscr(&cscore, 1))
        !           485:                            return TRUE;
        !           486:                        sum = 0;
        !           487:                        mego = ugo = FALSE;
        !           488:                        Tcnt = 0;
        !           489:                    }
        !           490:                }
        !           491:                else {                                  /* player plays */
        !           492:                    played = FALSE;
        !           493:                    if (pnum == 1) {
        !           494:                        crd = ph[0];
        !           495:                        msg("You play your last card");
        !           496:                    }
        !           497:                    else
        !           498:                        for (;;) {
        !           499:                            prhand(ph, pnum, Playwin, FALSE);
        !           500:                            crd = ph[infrom(ph, pnum, "Your play: ")];
        !           501:                            if (sum + VAL(crd.rank) <= 31)
        !           502:                                break;
        !           503:                            else
        !           504:                                msg("Total > 31 -- try again");
        !           505:                        }
        !           506:                    makeknown(&crd, 1);
        !           507:                    remove(crd, ph, pnum--);
        !           508:                    i = pegscore(crd, Table, Tcnt, sum);
        !           509:                    sum += VAL(crd.rank);
        !           510:                    Table[Tcnt++] = crd;
        !           511:                    if (i > 0) {
        !           512:                        msg(quiet ? "You got %d" : "You got %d points", i);
        !           513:                        if (chkscr(&pscore, i))
        !           514:                            return TRUE;
        !           515:                    }
        !           516:                    myturn = !myturn;
        !           517:                }
        !           518:            }
        !           519:            if (sum >= 31) {
        !           520:                if (!myturn)
        !           521:                    do_wait();
        !           522:                sum = 0;
        !           523:                mego = ugo = FALSE;
        !           524:                Tcnt = 0;
        !           525:                last = FALSE;                           /* disable last flag */
        !           526:            }
        !           527:            if (!pnum && !cnum)
        !           528:                break;                                  /* both done */
        !           529:        }
        !           530:        prhand(ph, pnum, Playwin, FALSE);
        !           531:        prhand(ch, cnum, Compwin, TRUE);
        !           532:        prtable(sum);
        !           533:        if (last)
        !           534:            if (played) {
        !           535:                msg(quiet ? "I get one for last" : "I get one point for last");
        !           536:                do_wait();
        !           537:                if (chkscr(&cscore, 1))
        !           538:                    return TRUE;
        !           539:            }
        !           540:            else {
        !           541:                msg(quiet ? "You get one for last" :
        !           542:                            "You get one point for last");
        !           543:                if (chkscr(&pscore, 1))
        !           544:                    return TRUE;
        !           545:            }
        !           546:        return FALSE;
        !           547: }
        !           548: 
        !           549: /*
        !           550:  * prtable:
        !           551:  *     Print out the table with the current score
        !           552:  */
        !           553: prtable(score)
        !           554: int    score;
        !           555: {
        !           556:        prhand(Table, Tcnt, Tablewin, FALSE);
        !           557:        mvwprintw(Tablewin, (Tcnt + 2) * 2, Tcnt + 1, "%2d", score);
        !           558:        wrefresh(Tablewin);
        !           559: }
        !           560: 
        !           561: /*
        !           562:  * score:
        !           563:  *     Handle the scoring of the hands
        !           564:  */
        !           565: score(mycrib)
        !           566: BOOLEAN                mycrib;
        !           567: {
        !           568:        sorthand(crib, CINHAND);
        !           569:        if (mycrib) {
        !           570:            if (plyrhand(phand, "hand"))
        !           571:                return TRUE;
        !           572:            if (comphand(chand, "hand"))
        !           573:                return TRUE;
        !           574:            do_wait();
        !           575:            if (comphand(crib, "crib"))
        !           576:                return TRUE;
        !           577:        }
        !           578:        else {
        !           579:            if (comphand(chand, "hand"))
        !           580:                return TRUE;
        !           581:            if (plyrhand(phand, "hand"))
        !           582:                return TRUE;
        !           583:            if (plyrhand(crib, "crib"))
        !           584:                return TRUE;
        !           585:        }
        !           586:        return FALSE;
        !           587: }

unix.superglobalmegacorp.com

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