Annotation of 43BSD/games/cribbage/crib.c, revision 1.1.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.