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

unix.superglobalmegacorp.com

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