Annotation of 42BSD/games/cribbage/crib.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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