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

unix.superglobalmegacorp.com

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