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