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

unix.superglobalmegacorp.com

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