Annotation of 43BSD/games/cribbage/io.c, revision 1.1

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

unix.superglobalmegacorp.com

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