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

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

unix.superglobalmegacorp.com

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