Annotation of 43BSDReno/games/cribbage/io.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: static char sccsid[] = "@(#)io.c       5.6 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: # include      <curses.h>
                     25: # include      <ctype.h>
                     26: # include      <signal.h>
                     27: # include      "deck.h"
                     28: # include      "cribbage.h"
                     29: # include      "cribcur.h"
                     30: 
                     31: # define       LINESIZE                128
                     32: 
                     33: # ifdef CTRL
                     34: # undef CTRL
                     35: # endif
                     36: # define       CTRL(X)                 ('X' - 'A' + 1)
                     37: 
                     38: # ifdef        notdef                          /* defined in curses.h */
                     39: #      define  erasechar()     _tty.sg_erase
                     40: #      define  killchar()      _tty.sg_kill
                     41: # endif
                     42: 
                     43: char           linebuf[ LINESIZE ];
                     44: 
                     45: char           *rankname[ RANKS ]      = { "ACE", "TWO", "THREE", "FOUR",
                     46:                                            "FIVE", "SIX", "SEVEN", "EIGHT",
                     47:                                            "NINE", "TEN", "JACK", "QUEEN",
                     48:                                            "KING" };
                     49: 
                     50: char            *rankchar[ RANKS ]      = { "A", "2", "3", "4", "5", "6", "7",
                     51:                                            "8", "9", "T", "J", "Q", "K" };
                     52: 
                     53: char            *suitname[ SUITS ]      = { "SPADES", "HEARTS", "DIAMONDS",
                     54:                                            "CLUBS" };
                     55: 
                     56: char            *suitchar[ SUITS ]      = { "S", "H", "D", "C" };
                     57: 
                     58: 
                     59: 
                     60: /*
                     61:  * msgcard:
                     62:  *     Call msgcrd in one of two forms
                     63:  */
                     64: msgcard(c, brief)
                     65: CARD           c;
                     66: BOOLEAN                brief;
                     67: {
                     68:        if (brief)
                     69:                return msgcrd(c, TRUE, (char *) NULL, TRUE);
                     70:        else
                     71:                return msgcrd(c, FALSE, " of ", FALSE);
                     72: }
                     73: 
                     74: 
                     75: 
                     76: /*
                     77:  * msgcrd:
                     78:  *     Print the value of a card in ascii
                     79:  */
                     80: msgcrd(c, brfrank, mid, brfsuit)
                     81: CARD           c;
                     82: char           *mid;
                     83: BOOLEAN                brfrank,  brfsuit;
                     84: {
                     85:        if (c.rank == EMPTY || c.suit == EMPTY)
                     86:            return FALSE;
                     87:        if (brfrank)
                     88:            addmsg("%1.1s", rankchar[c.rank]);
                     89:        else
                     90:            addmsg(rankname[c.rank]);
                     91:        if (mid != NULL)
                     92:            addmsg(mid);
                     93:        if (brfsuit)
                     94:            addmsg("%1.1s", suitchar[c.suit]);
                     95:        else
                     96:            addmsg(suitname[c.suit]);
                     97:        return TRUE;
                     98: }
                     99: 
                    100: /*
                    101:  * printcard:
                    102:  *     Print out a card.
                    103:  */
                    104: printcard(win, cardno, c, blank)
                    105: WINDOW         *win;
                    106: int            cardno;
                    107: CARD           c;
                    108: BOOLEAN                blank;
                    109: {
                    110:        prcard(win, cardno * 2, cardno, c, blank);
                    111: }
                    112: 
                    113: /*
                    114:  * prcard:
                    115:  *     Print out a card on the window at the specified location
                    116:  */
                    117: prcard(win, y, x, c, blank)
                    118: WINDOW         *win;
                    119: int            y, x;
                    120: CARD           c;
                    121: BOOLEAN                blank;
                    122: {
                    123:        if (c.rank == EMPTY)
                    124:            return;
                    125:        mvwaddstr(win, y + 0, x, "+-----+");
                    126:        mvwaddstr(win, y + 1, x, "|     |");
                    127:        mvwaddstr(win, y + 2, x, "|     |");
                    128:        mvwaddstr(win, y + 3, x, "|     |");
                    129:        mvwaddstr(win, y + 4, x, "+-----+");
                    130:        if (!blank) {
                    131:                mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]);
                    132:                waddch(win, suitchar[c.suit][0]);
                    133:                mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]);
                    134:                waddch(win, suitchar[c.suit][0]);
                    135:        }
                    136: }
                    137: 
                    138: /*
                    139:  * prhand:
                    140:  *     Print a hand of n cards
                    141:  */
                    142: prhand(h, n, win, blank)
                    143: CARD           h[];
                    144: int            n;
                    145: WINDOW         *win;
                    146: BOOLEAN                blank;
                    147: {
                    148:        register int    i;
                    149: 
                    150:        werase(win);
                    151:        for (i = 0; i < n; i++)
                    152:            printcard(win, i, *h++, blank);
                    153:        wrefresh(win);
                    154: }
                    155: 
                    156: 
                    157: 
                    158: /*
                    159:  * infrom:
                    160:  *     reads a card, supposedly in hand, accepting unambigous brief
                    161:  *     input, returns the index of the card found...
                    162:  */
                    163: infrom(hand, n, prompt)
                    164: CARD           hand[];
                    165: int            n;
                    166: char           *prompt;
                    167: {
                    168:        register int           i, j;
                    169:        CARD                    crd;
                    170: 
                    171:        if (n < 1) {
                    172:            printf("\nINFROM: %d = n < 1!!\n", n);
                    173:            exit(74);
                    174:        }
                    175:        for (;;) {
                    176:            msg(prompt);
                    177:            if (incard(&crd)) {                 /* if card is full card */
                    178:                if (!isone(crd, hand, n))
                    179:                    msg("That's not in your hand");
                    180:                else {
                    181:                    for (i = 0; i < n; i++)
                    182:                        if (hand[i].rank == crd.rank &&
                    183:                            hand[i].suit == crd.suit)
                    184:                                break;
                    185:                    if (i >= n) {
                    186:                        printf("\nINFROM: isone or something messed up\n");
                    187:                        exit(77);
                    188:                    }
                    189:                    return i;
                    190:                }
                    191:            }
                    192:            else                                /* if not full card... */
                    193:                if (crd.rank != EMPTY) {
                    194:                    for (i = 0; i < n; i++)
                    195:                        if (hand[i].rank == crd.rank)
                    196:                                break;
                    197:                    if (i >= n)
                    198:                        msg("No such rank in your hand");
                    199:                    else {
                    200:                        for (j = i + 1; j < n; j++)
                    201:                            if (hand[j].rank == crd.rank)
                    202:                                break;
                    203:                        if (j < n)
                    204:                            msg("Ambiguous rank");
                    205:                        else
                    206:                            return i;
                    207:                    }
                    208:                }
                    209:                else
                    210:                    msg("Sorry, I missed that");
                    211:        }
                    212:        /* NOTREACHED */
                    213: }
                    214: 
                    215: 
                    216: 
                    217: /*
                    218:  * incard:
                    219:  *     Inputs a card in any format.  It reads a line ending with a CR
                    220:  *     and then parses it.
                    221:  */
                    222: incard(crd)
                    223: CARD           *crd;
                    224: {
                    225:        char            *getline();
                    226:        register int    i;
                    227:        int             rnk, sut;
                    228:        char            *line, *p, *p1;
                    229:        BOOLEAN         retval;
                    230: 
                    231:        retval = FALSE;
                    232:        rnk = sut = EMPTY;
                    233:        if (!(line = getline()))
                    234:                goto gotit;
                    235:        p = p1 = line;
                    236:        while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
                    237:        *p1++ = NULL;
                    238:        if(  *p == NULL  )  goto  gotit;
                    239:                        /* IMPORTANT: no real card has 2 char first name */
                    240:        if(  strlen(p) == 2  )  {               /* check for short form */
                    241:            rnk = EMPTY;
                    242:            for( i = 0; i < RANKS; i++ )  {
                    243:                if(  *p == *rankchar[i]  )  {
                    244:                    rnk = i;
                    245:                    break;
                    246:                }
                    247:            }
                    248:            if(  rnk == EMPTY  )  goto  gotit;     /* it's nothing... */
                    249:            ++p;                                /* advance to next char */
                    250:            sut = EMPTY;
                    251:            for( i = 0; i < SUITS; i++ )  {
                    252:                if(  *p == *suitchar[i]  )  {
                    253:                    sut = i;
                    254:                    break;
                    255:                }
                    256:            }
                    257:            if(  sut != EMPTY  )  retval = TRUE;
                    258:            goto  gotit;
                    259:        }
                    260:        rnk = EMPTY;
                    261:        for( i = 0; i < RANKS; i++ )  {
                    262:            if(  !strcmp( p, rankname[i] )  ||  !strcmp( p, rankchar[i] )  )  {
                    263:                rnk = i;
                    264:                break;
                    265:            }
                    266:        }
                    267:        if(  rnk == EMPTY  )  goto  gotit;
                    268:        p = p1;
                    269:        while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
                    270:        *p1++ = NULL;
                    271:        if(  *p == NULL  )  goto  gotit;
                    272:        if(  !strcmp( "OF", p )  )  {
                    273:            p = p1;
                    274:            while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
                    275:            *p1++ = NULL;
                    276:            if(  *p == NULL  )  goto  gotit;
                    277:        }
                    278:        sut = EMPTY;
                    279:        for( i = 0; i < SUITS; i++ )  {
                    280:            if(  !strcmp( p, suitname[i] )  ||  !strcmp( p, suitchar[i] )  )  {
                    281:                sut = i;
                    282:                break;
                    283:            }
                    284:        }
                    285:        if(  sut != EMPTY  )  retval = TRUE;
                    286: gotit:
                    287:        (*crd).rank = rnk;
                    288:        (*crd).suit = sut;
                    289:        return( retval );
                    290: }
                    291: 
                    292: 
                    293: 
                    294: /*
                    295:  * getuchar:
                    296:  *     Reads and converts to upper case
                    297:  */
                    298: getuchar()
                    299: {
                    300:        register int            c;
                    301: 
                    302:        c = readchar();
                    303:        if (islower(c))
                    304:            c = toupper(c);
                    305:        waddch(Msgwin, c);
                    306:        return c;
                    307: }
                    308: 
                    309: /*
                    310:  * number:
                    311:  *     Reads in a decimal number and makes sure it is between "lo" and
                    312:  *     "hi" inclusive.
                    313:  */
                    314: number(lo, hi, prompt)
                    315: int            lo, hi;
                    316: char           *prompt;
                    317: {
                    318:        char                    *getline();
                    319:        register char           *p;
                    320:        register int            sum;
                    321: 
                    322:        sum = 0;
                    323:        for (;;) {
                    324:            msg(prompt);
                    325:            if(!(p = getline()) || *p == NULL) {
                    326:                msg(quiet ? "Not a number" : "That doesn't look like a number");
                    327:                continue;
                    328:            }
                    329:            sum = 0;
                    330: 
                    331:            if (!isdigit(*p))
                    332:                sum = lo - 1;
                    333:            else
                    334:                while (isdigit(*p)) {
                    335:                    sum = 10 * sum + (*p - '0');
                    336:                    ++p;
                    337:                }
                    338: 
                    339:            if (*p != ' ' && *p != '\t' && *p != NULL)
                    340:                sum = lo - 1;
                    341:            if (sum >= lo && sum <= hi)
                    342:                return sum;
                    343:            if (sum == lo - 1)
                    344:                msg("that doesn't look like a number, try again --> ");
                    345:            else
                    346:                msg("%d is not between %d and %d inclusive, try again --> ",
                    347:                                                                sum, lo, hi);
                    348:        }
                    349: }
                    350: 
                    351: /*
                    352:  * msg:
                    353:  *     Display a message at the top of the screen.
                    354:  */
                    355: char           Msgbuf[BUFSIZ] = { '\0' };
                    356: 
                    357: int            Mpos = 0;
                    358: 
                    359: static int     Newpos = 0;
                    360: 
                    361: /* VARARGS1 */
                    362: msg(fmt, args)
                    363: char   *fmt;
                    364: int    args;
                    365: {
                    366:     doadd(fmt, &args);
                    367:     endmsg();
                    368: }
                    369: 
                    370: /*
                    371:  * addmsg:
                    372:  *     Add things to the current message
                    373:  */
                    374: /* VARARGS1 */
                    375: addmsg(fmt, args)
                    376: char   *fmt;
                    377: int    args;
                    378: {
                    379:     doadd(fmt, &args);
                    380: }
                    381: 
                    382: /*
                    383:  * endmsg:
                    384:  *     Display a new msg.
                    385:  */
                    386: 
                    387: int    Lineno = 0;
                    388: 
                    389: endmsg()
                    390: {
                    391:     register int       len;
                    392:     register char      *mp, *omp;
                    393:     static int         lastline = 0;
                    394: 
                    395:     /*
                    396:      * All messages should start with uppercase
                    397:      */
                    398:     mvaddch(lastline + Y_MSG_START, SCORE_X, ' ');
                    399:     if (islower(Msgbuf[0]) && Msgbuf[1] != ')')
                    400:        Msgbuf[0] = toupper(Msgbuf[0]);
                    401:     mp = Msgbuf;
                    402:     len = strlen(mp);
                    403:     if (len / MSG_X + Lineno >= MSG_Y) {
                    404:        while (Lineno < MSG_Y) {
                    405:            wmove(Msgwin, Lineno++, 0);
                    406:            wclrtoeol(Msgwin);
                    407:        }
                    408:        Lineno = 0;
                    409:     }
                    410:     mvaddch(Lineno + Y_MSG_START, SCORE_X, '*');
                    411:     lastline = Lineno;
                    412:     do {
                    413:        mvwaddstr(Msgwin, Lineno, 0, mp);
                    414:        if ((len = strlen(mp)) > MSG_X) {
                    415:            omp = mp;
                    416:            for (mp = &mp[MSG_X-1]; *mp != ' '; mp--)
                    417:                continue;
                    418:            while (*mp == ' ')
                    419:                mp--;
                    420:            mp++;
                    421:            wmove(Msgwin, Lineno, mp - omp);
                    422:            wclrtoeol(Msgwin);
                    423:        }
                    424:        if (++Lineno >= MSG_Y)
                    425:            Lineno = 0;
                    426:     } while (len > MSG_X);
                    427:     wclrtoeol(Msgwin);
                    428:     Mpos = len;
                    429:     Newpos = 0;
                    430:     wrefresh(Msgwin);
                    431:     refresh();
                    432:     wrefresh(Msgwin);
                    433: }
                    434: 
                    435: /*
                    436:  * doadd:
                    437:  *     Perform an add onto the message buffer
                    438:  */
                    439: doadd(fmt, args)
                    440: char   *fmt;
                    441: int    *args;
                    442: {
                    443:     static FILE        junk;
                    444: 
                    445:     /*
                    446:      * Do the printf into Msgbuf
                    447:      */
                    448:     junk._flag = _IOWRT + _IOSTRG;
                    449:     junk._ptr = &Msgbuf[Newpos];
                    450:     junk._cnt = 32767;
                    451:     _doprnt(fmt, args, &junk);
                    452:     putc('\0', &junk);
                    453:     Newpos = strlen(Msgbuf);
                    454: }
                    455: 
                    456: /*
                    457:  * do_wait:
                    458:  *     Wait for the user to type ' ' before doing anything else
                    459:  */
                    460: do_wait()
                    461: {
                    462:     register int line;
                    463:     static char prompt[] = { '-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0' };
                    464: 
                    465:     if (Mpos + sizeof prompt < MSG_X)
                    466:        wmove(Msgwin, Lineno > 0 ? Lineno - 1 : MSG_Y - 1, Mpos);
                    467:     else {
                    468:        mvwaddch(Msgwin, Lineno, 0, ' ');
                    469:        wclrtoeol(Msgwin);
                    470:        if (++Lineno >= MSG_Y)
                    471:            Lineno = 0;
                    472:     }
                    473:     waddstr(Msgwin, prompt);
                    474:     wrefresh(Msgwin);
                    475:     wait_for(' ');
                    476: }
                    477: 
                    478: /*
                    479:  * wait_for
                    480:  *     Sit around until the guy types the right key
                    481:  */
                    482: wait_for(ch)
                    483: register char  ch;
                    484: {
                    485:     register char      c;
                    486: 
                    487:     if (ch == '\n')
                    488:        while ((c = readchar()) != '\n')
                    489:            continue;
                    490:     else
                    491:        while (readchar() != ch)
                    492:            continue;
                    493: }
                    494: 
                    495: /*
                    496:  * readchar:
                    497:  *     Reads and returns a character, checking for gross input errors
                    498:  */
                    499: readchar()
                    500: {
                    501:     register int       cnt, y, x;
                    502:     auto char          c;
                    503: 
                    504: over:
                    505:     cnt = 0;
                    506:     while (read(0, &c, 1) <= 0)
                    507:        if (cnt++ > 100) {      /* if we are getting infinite EOFs */
                    508:                bye();          /* quit the game */
                    509:                exit(1);
                    510:        }
                    511:     if (c == CTRL(L)) {
                    512:        wrefresh(curscr);
                    513:        goto over;
                    514:     }
                    515:     if (c == '\r')
                    516:        return '\n';
                    517:     else
                    518:        return c;
                    519: }
                    520: 
                    521: /*
                    522:  * getline:
                    523:  *      Reads the next line up to '\n' or EOF.  Multiple spaces are
                    524:  *     compressed to one space; a space is inserted before a ','
                    525:  */
                    526: char *
                    527: getline()
                    528: {
                    529:     register char      *sp;
                    530:     register int       c, oy, ox;
                    531:     register WINDOW    *oscr;
                    532: 
                    533:     oscr = stdscr;
                    534:     stdscr = Msgwin;
                    535:     getyx(stdscr, oy, ox);
                    536:     refresh();
                    537:     /*
                    538:      * loop reading in the string, and put it in a temporary buffer
                    539:      */
                    540:     for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
                    541:        if (c == -1)
                    542:            continue;
                    543:        else if (c == erasechar()) {    /* process erase character */
                    544:            if (sp > linebuf) {
                    545:                register int i;
                    546: 
                    547:                sp--;
                    548:                for (i = strlen(unctrl(*sp)); i; i--)
                    549:                    addch('\b');
                    550:            }
                    551:            continue;
                    552:        }
                    553:        else if (c == killchar()) {     /* process kill character */
                    554:            sp = linebuf;
                    555:            move(oy, ox);
                    556:            continue;
                    557:        }
                    558:        else if (sp == linebuf && c == ' ')
                    559:            continue;
                    560:        if (sp >= &linebuf[LINESIZE-1] || !(isprint(c) || c == ' '))
                    561:            putchar(CTRL(G));
                    562:        else {
                    563:            if (islower(c))
                    564:                c = toupper(c);
                    565:            *sp++ = c;
                    566:            addstr(unctrl(c));
                    567:            Mpos++;
                    568:        }
                    569:     }
                    570:     *sp = '\0';
                    571:     stdscr = oscr;
                    572:     return linebuf;
                    573: }
                    574: 
                    575: rint()
                    576: {
                    577:        bye();
                    578:        exit(1);
                    579: }
                    580: 
                    581: /*
                    582:  * bye:
                    583:  *     Leave the program, cleaning things up as we go.
                    584:  */
                    585: bye()
                    586: {
                    587:        signal(SIGINT, SIG_IGN);
                    588:        mvcur(0, COLS - 1, LINES - 1, 0);
                    589:        fflush(stdout);
                    590:        endwin();
                    591:        putchar('\n');
                    592: }

unix.superglobalmegacorp.com

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