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

unix.superglobalmegacorp.com

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