Annotation of 43BSDTahoe/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.
        !             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.