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