Annotation of 43BSDReno/games/mille/move.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 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[] = "@(#)move.c     5.4 (Berkeley) 6/1/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #include       "mille.h"
        !            25: #ifndef        unctrl
        !            26: #include       "unctrl.h"
        !            27: #endif
        !            28: 
        !            29: # ifdef        attron
        !            30: #      include <term.h>
        !            31: #      define  _tty    cur_term->Nttyb
        !            32: # endif        attron
        !            33: 
        !            34: /*
        !            35:  * @(#)move.c  1.2 (Berkeley) 3/28/83
        !            36:  */
        !            37: 
        !            38: #undef CTRL
        !            39: #define        CTRL(c)         (c - 'A' + 1)
        !            40: 
        !            41: char   *Movenames[] = {
        !            42:                "M_DISCARD", "M_DRAW", "M_PLAY", "M_ORDER"
        !            43:        };
        !            44: 
        !            45: domove()
        !            46: {
        !            47:        reg PLAY        *pp;
        !            48:        reg int         i, j;
        !            49:        reg bool        goodplay;
        !            50: 
        !            51:        pp = &Player[Play];
        !            52:        if (Play == PLAYER)
        !            53:                getmove();
        !            54:        else
        !            55:                calcmove();
        !            56:        Next = FALSE;
        !            57:        goodplay = TRUE;
        !            58:        switch (Movetype) {
        !            59:          case M_DISCARD:
        !            60:                if (haspicked(pp)) {
        !            61:                        if (pp->hand[Card_no] == C_INIT)
        !            62:                                if (Card_no == 6)
        !            63:                                        Finished = TRUE;
        !            64:                                else
        !            65:                                        error("no card there");
        !            66:                        else {
        !            67:                                if (issafety(pp->hand[Card_no])) {
        !            68:                                        error("discard a safety?");
        !            69:                                        goodplay = FALSE;
        !            70:                                        break;
        !            71:                                }
        !            72:                                Discard = pp->hand[Card_no];
        !            73:                                pp->hand[Card_no] = C_INIT;
        !            74:                                Next = TRUE;
        !            75:                                if (Play == PLAYER)
        !            76:                                        account(Discard);
        !            77:                        }
        !            78:                }
        !            79:                else
        !            80:                        error("must pick first");
        !            81:                break;
        !            82:          case M_PLAY:
        !            83:                goodplay = playcard(pp);
        !            84:                break;
        !            85:          case M_DRAW:
        !            86:                Card_no = 0;
        !            87:                if (Topcard <= Deck)
        !            88:                        error("no more cards");
        !            89:                else if (haspicked(pp))
        !            90:                        error("already picked");
        !            91:                else {
        !            92:                        pp->hand[0] = *--Topcard;
        !            93: #ifdef DEBUG
        !            94:                        if (Debug)
        !            95:                                fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
        !            96: #endif
        !            97: acc:
        !            98:                        if (Play == COMP) {
        !            99:                                account(*Topcard);
        !           100:                                if (issafety(*Topcard))
        !           101:                                        pp->safety[*Topcard-S_CONV] = S_IN_HAND;
        !           102:                        }
        !           103:                        if (pp->hand[1] == C_INIT && Topcard > Deck) {
        !           104:                                Card_no = 1;
        !           105:                                pp->hand[1] = *--Topcard;
        !           106: #ifdef DEBUG
        !           107:                                if (Debug)
        !           108:                                        fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
        !           109: #endif
        !           110:                                goto acc;
        !           111:                        }
        !           112:                        pp->new_battle = FALSE;
        !           113:                        pp->new_speed = FALSE;
        !           114:                }
        !           115:                break;
        !           116: 
        !           117:          case M_ORDER:
        !           118:                break;
        !           119:        }
        !           120:        /*
        !           121:         * move blank card to top by one of two methods.  If the
        !           122:         * computer's hand was sorted, the randomness for picking
        !           123:         * between equally valued cards would be lost
        !           124:         */
        !           125:        if (Order && Movetype != M_DRAW && goodplay && pp == &Player[PLAYER])
        !           126:                sort(pp->hand);
        !           127:        else
        !           128:                for (i = 1; i < HAND_SZ; i++)
        !           129:                        if (pp->hand[i] == C_INIT) {
        !           130:                                for (j = 0; pp->hand[j] == C_INIT; j++)
        !           131:                                        if (j >= HAND_SZ) {
        !           132:                                                j = 0;
        !           133:                                                break;
        !           134:                                        }
        !           135:                                pp->hand[i] = pp->hand[j];
        !           136:                                pp->hand[j] = C_INIT;
        !           137:                        }
        !           138:        if (Topcard <= Deck)
        !           139:                check_go();
        !           140:        if (Next)
        !           141:                nextplay();
        !           142: }
        !           143: 
        !           144: /*
        !           145:  *     Check and see if either side can go.  If they cannot,
        !           146:  * the game is over
        !           147:  */
        !           148: check_go() {
        !           149: 
        !           150:        reg CARD        card;
        !           151:        reg PLAY        *pp, *op;
        !           152:        reg int         i;
        !           153: 
        !           154:        for (pp = Player; pp < &Player[2]; pp++) {
        !           155:                op = (pp == &Player[COMP] ? &Player[PLAYER] : &Player[COMP]);
        !           156:                for (i = 0; i < HAND_SZ; i++) {
        !           157:                        card = pp->hand[i];
        !           158:                        if (issafety(card) || canplay(pp, op, card)) {
        !           159: #ifdef DEBUG
        !           160:                                if (Debug) {
        !           161:                                        fprintf(outf, "CHECK_GO: can play %s (%d), ", C_name[card], card);
        !           162:                                        fprintf(outf, "issafety(card) = %d, ", issafety(card));
        !           163:                                        fprintf(outf, "canplay(pp, op, card) = %d\n", canplay(pp, op, card));
        !           164:                                }
        !           165: #endif
        !           166:                                return;
        !           167:                        }
        !           168: #ifdef DEBUG
        !           169:                        else if (Debug)
        !           170:                                fprintf(outf, "CHECK_GO: cannot play %s\n",
        !           171:                                    C_name[card]);
        !           172: #endif
        !           173:                }
        !           174:        }
        !           175:        Finished = TRUE;
        !           176: }
        !           177: 
        !           178: playcard(pp)
        !           179: reg PLAY       *pp;
        !           180: {
        !           181:        reg int         v;
        !           182:        reg CARD        card;
        !           183: 
        !           184:        /*
        !           185:         * check and see if player has picked
        !           186:         */
        !           187:        switch (pp->hand[Card_no]) {
        !           188:          default:
        !           189:                if (!haspicked(pp))
        !           190: mustpick:
        !           191:                        return error("must pick first");
        !           192:          case C_GAS_SAFE:      case C_SPARE_SAFE:
        !           193:          case C_DRIVE_SAFE:    case C_RIGHT_WAY:
        !           194:                break;
        !           195:        }
        !           196: 
        !           197:        card = pp->hand[Card_no];
        !           198: #ifdef DEBUG
        !           199:        if (Debug)
        !           200:                fprintf(outf, "PLAYCARD: Card = %s\n", C_name[card]);
        !           201: #endif
        !           202:        Next = FALSE;
        !           203:        switch (card) {
        !           204:          case C_200:
        !           205:                if (pp->nummiles[C_200] == 2)
        !           206:                        return error("only two 200's per hand");
        !           207:          case C_100:   case C_75:
        !           208:                if (pp->speed == C_LIMIT)
        !           209:                        return error("limit of 50");
        !           210:          case C_50:
        !           211:                if (pp->mileage + Value[card] > End)
        !           212:                        return error("puts you over %d", End);
        !           213:          case C_25:
        !           214:                if (!pp->can_go)
        !           215:                        return error("cannot move now");
        !           216:                pp->nummiles[card]++;
        !           217:                v = Value[card];
        !           218:                pp->total += v;
        !           219:                pp->hand_tot += v;
        !           220:                if ((pp->mileage += v) == End)
        !           221:                        check_ext(FALSE);
        !           222:                break;
        !           223: 
        !           224:          case C_GAS:   case C_SPARE:   case C_REPAIRS:
        !           225:                if (pp->battle != opposite(card))
        !           226:                        return error("can't play \"%s\"", C_name[card]);
        !           227:                pp->battle = card;
        !           228:                if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
        !           229:                        pp->can_go = TRUE;
        !           230:                break;
        !           231: 
        !           232:          case C_GO:
        !           233:                if (pp->battle != C_INIT && pp->battle != C_STOP
        !           234:                    && !isrepair(pp->battle))
        !           235:                        return error("cannot play \"Go\" on a \"%s\"",
        !           236:                            C_name[pp->battle]);
        !           237:                pp->battle = C_GO;
        !           238:                pp->can_go = TRUE;
        !           239:                break;
        !           240: 
        !           241:          case C_END_LIMIT:
        !           242:                if (pp->speed != C_LIMIT)
        !           243:                        return error("not limited");
        !           244:                pp->speed = C_END_LIMIT;
        !           245:                break;
        !           246: 
        !           247:          case C_EMPTY: case C_FLAT:    case C_CRASH:
        !           248:          case C_STOP:
        !           249:                pp = &Player[other(Play)];
        !           250:                if (!pp->can_go)
        !           251:                        return error("opponent cannot go");
        !           252:                else if (pp->safety[safety(card) - S_CONV] == S_PLAYED)
        !           253: protected:
        !           254:                        return error("opponent is protected");
        !           255:                pp->battle = card;
        !           256:                pp->new_battle = TRUE;
        !           257:                pp->can_go = FALSE;
        !           258:                pp = &Player[Play];
        !           259:                break;
        !           260: 
        !           261:          case C_LIMIT:
        !           262:                pp = &Player[other(Play)];
        !           263:                if (pp->speed == C_LIMIT)
        !           264:                        return error("opponent has limit");
        !           265:                if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
        !           266:                        goto protected;
        !           267:                pp->speed = C_LIMIT;
        !           268:                pp->new_speed = TRUE;
        !           269:                pp = &Player[Play];
        !           270:                break;
        !           271: 
        !           272:          case C_GAS_SAFE:      case C_SPARE_SAFE:
        !           273:          case C_DRIVE_SAFE:    case C_RIGHT_WAY:
        !           274:                if (pp->battle == opposite(card)
        !           275:                    || (card == C_RIGHT_WAY && pp->speed == C_LIMIT)) {
        !           276:                        if (!(card == C_RIGHT_WAY && !isrepair(pp->battle))) {
        !           277:                                pp->battle = C_GO;
        !           278:                                pp->can_go = TRUE;
        !           279:                        }
        !           280:                        if (card == C_RIGHT_WAY && pp->speed == C_LIMIT)
        !           281:                                pp->speed = C_INIT;
        !           282:                        if (pp->new_battle
        !           283:                            || (pp->new_speed && card == C_RIGHT_WAY)) {
        !           284:                                pp->coups[card - S_CONV] = TRUE;
        !           285:                                pp->total += SC_COUP;
        !           286:                                pp->hand_tot += SC_COUP;
        !           287:                                pp->coupscore += SC_COUP;
        !           288:                        }
        !           289:                }
        !           290:                /*
        !           291:                 * if not coup, must pick first
        !           292:                 */
        !           293:                else if (pp->hand[0] == C_INIT && Topcard > Deck)
        !           294:                        goto mustpick;
        !           295:                pp->safety[card - S_CONV] = S_PLAYED;
        !           296:                pp->total += SC_SAFETY;
        !           297:                pp->hand_tot += SC_SAFETY;
        !           298:                if ((pp->safescore += SC_SAFETY) == NUM_SAFE * SC_SAFETY) {
        !           299:                        pp->total += SC_ALL_SAFE;
        !           300:                        pp->hand_tot += SC_ALL_SAFE;
        !           301:                }
        !           302:                if (card == C_RIGHT_WAY) {
        !           303:                        if (pp->speed == C_LIMIT)
        !           304:                                pp->speed = C_INIT;
        !           305:                        if (pp->battle == C_STOP || pp->battle == C_INIT) {
        !           306:                                pp->can_go = TRUE;
        !           307:                                pp->battle = C_INIT;
        !           308:                        }
        !           309:                        if (!pp->can_go && isrepair(pp->battle))
        !           310:                                pp->can_go = TRUE;
        !           311:                }
        !           312:                Next = -1;
        !           313:                break;
        !           314: 
        !           315:          case C_INIT:
        !           316:                error("no card there");
        !           317:                Next = -1;
        !           318:                break;
        !           319:        }
        !           320:        if (pp == &Player[PLAYER])
        !           321:                account(card);
        !           322:        pp->hand[Card_no] = C_INIT;
        !           323:        Next = (Next == -1 ? FALSE : TRUE);
        !           324:        return TRUE;
        !           325: }
        !           326: 
        !           327: getmove()
        !           328: {
        !           329:        reg char        c, *sp;
        !           330: #ifdef EXTRAP
        !           331:        static bool     last_ex = FALSE;        /* set if last command was E */
        !           332: 
        !           333:        if (last_ex) {
        !           334:                undoex();
        !           335:                prboard();
        !           336:                last_ex = FALSE;
        !           337:        }
        !           338: #endif
        !           339:        for (;;) {
        !           340:                prompt(MOVEPROMPT);
        !           341:                leaveok(Board, FALSE);
        !           342:                refresh();
        !           343:                while ((c = readch()) == killchar() || c == erasechar())
        !           344:                        continue;
        !           345:                if (islower(c))
        !           346:                        c = toupper(c);
        !           347:                if (isprint(c) && !isspace(c)) {
        !           348:                        addch(c);
        !           349:                        refresh();
        !           350:                }
        !           351:                switch (c) {
        !           352:                  case 'P':             /* Pick */
        !           353:                        Movetype = M_DRAW;
        !           354:                        goto ret;
        !           355:                  case 'U':             /* Use Card */
        !           356:                  case 'D':             /* Discard Card */
        !           357:                        if ((Card_no = getcard()) < 0)
        !           358:                                break;
        !           359:                        Movetype = (c == 'U' ? M_PLAY : M_DISCARD);
        !           360:                        goto ret;
        !           361:                  case 'O':             /* Order */
        !           362:                        Order = !Order;
        !           363:                        if (Window == W_SMALL) {
        !           364:                                if (!Order)
        !           365:                                        mvwaddstr(Score, 12, 21,
        !           366:                                                  "o: order hand");
        !           367:                                else
        !           368:                                        mvwaddstr(Score, 12, 21,
        !           369:                                                  "o: stop ordering");
        !           370:                                wclrtoeol(Score);
        !           371:                        }
        !           372:                        Movetype = M_ORDER;
        !           373:                        goto ret;
        !           374:                  case 'Q':             /* Quit */
        !           375:                        rub();          /* Same as a rubout */
        !           376:                        break;
        !           377:                  case 'W':             /* Window toggle */
        !           378:                        Window = nextwin(Window);
        !           379:                        newscore();
        !           380:                        prscore(TRUE);
        !           381:                        wrefresh(Score);
        !           382:                        break;
        !           383:                  case 'R':             /* Redraw screen */
        !           384:                  case CTRL('L'):
        !           385:                        wrefresh(curscr);
        !           386:                        break;
        !           387:                  case 'S':             /* Save game */
        !           388:                        On_exit = FALSE;
        !           389:                        save();
        !           390:                        break;
        !           391:                  case 'E':             /* Extrapolate */
        !           392: #ifdef EXTRAP
        !           393:                        if (last_ex)
        !           394:                                break;
        !           395:                        Finished = TRUE;
        !           396:                        if (Window != W_FULL)
        !           397:                                newscore();
        !           398:                        prscore(FALSE);
        !           399:                        wrefresh(Score);
        !           400:                        last_ex = TRUE;
        !           401:                        Finished = FALSE;
        !           402: #else
        !           403:                        error("%c: command not implemented", c);
        !           404: #endif
        !           405:                        break;
        !           406:                  case '\r':            /* Ignore RETURNs and   */
        !           407:                  case '\n':            /* Line Feeds           */
        !           408:                  case ' ':             /* Spaces               */
        !           409:                  case '\0':            /* and nulls            */
        !           410:                        break;
        !           411: #ifdef DEBUG
        !           412:                  case 'Z':             /* Debug code */
        !           413:                        if (!Debug && outf == NULL) {
        !           414:                                char    buf[MAXPATHLEN];
        !           415: 
        !           416:                                prompt(FILEPROMPT);
        !           417:                                leaveok(Board, FALSE);
        !           418:                                refresh();
        !           419:                                sp = buf;
        !           420:                                while ((*sp = readch()) != '\n') {
        !           421:                                        if (*sp == killchar())
        !           422:                                                goto over;
        !           423:                                        else if (*sp == erasechar()) {
        !           424:                                                if (--sp < buf)
        !           425:                                                        sp = buf;
        !           426:                                                else {
        !           427:                                                        addch('\b');
        !           428:                                                        if (*sp < ' ')
        !           429:                                                            addch('\b');
        !           430:                                                        clrtoeol();
        !           431:                                                }
        !           432:                                        }
        !           433:                                        else
        !           434:                                                addstr(unctrl(*sp++));
        !           435:                                        refresh();
        !           436:                                }
        !           437:                                *sp = '\0';
        !           438:                                leaveok(Board, TRUE);
        !           439:                                if ((outf = fopen(buf, "w")) == NULL)
        !           440:                                        perror(buf);
        !           441:                                setbuf(outf, (char *)NULL);
        !           442:                        }
        !           443:                        Debug = !Debug;
        !           444:                        break;
        !           445: #endif
        !           446:                  default:
        !           447:                        error("unknown command: %s", unctrl(c));
        !           448:                        break;
        !           449:                }
        !           450:        }
        !           451: ret:
        !           452:        leaveok(Board, TRUE);
        !           453: }
        !           454: /*
        !           455:  * return whether or not the player has picked
        !           456:  */
        !           457: haspicked(pp)
        !           458: reg PLAY       *pp; {
        !           459: 
        !           460:        reg int card;
        !           461: 
        !           462:        if (Topcard <= Deck)
        !           463:                return TRUE;
        !           464:        switch (pp->hand[Card_no]) {
        !           465:          case C_GAS_SAFE:      case C_SPARE_SAFE:
        !           466:          case C_DRIVE_SAFE:    case C_RIGHT_WAY:
        !           467:                card = 1;
        !           468:                break;
        !           469:          default:
        !           470:                card = 0;
        !           471:                break;
        !           472:        }
        !           473:        return (pp->hand[card] != C_INIT);
        !           474: }
        !           475: 
        !           476: account(card)
        !           477: reg CARD       card; {
        !           478: 
        !           479:        reg CARD        oppos;
        !           480: 
        !           481:        if (card == C_INIT)
        !           482:                return;
        !           483:        ++Numseen[card];
        !           484:        if (Play == COMP)
        !           485:                switch (card) {
        !           486:                  case C_GAS_SAFE:
        !           487:                  case C_SPARE_SAFE:
        !           488:                  case C_DRIVE_SAFE:
        !           489:                        oppos = opposite(card);
        !           490:                        Numgos += Numcards[oppos] - Numseen[oppos];
        !           491:                        break;
        !           492:                  case C_CRASH:
        !           493:                  case C_FLAT:
        !           494:                  case C_EMPTY:
        !           495:                  case C_STOP:
        !           496:                        Numgos++;
        !           497:                        break;
        !           498:                }
        !           499: }
        !           500: 
        !           501: prompt(promptno)
        !           502: int    promptno;
        !           503: {
        !           504:        static char     *names[] = {
        !           505:                                ">>:Move:",
        !           506:                                "Really?",
        !           507:                                "Another hand?",
        !           508:                                "Another game?",
        !           509:                                "Save game?",
        !           510:                                "Same file?",
        !           511:                                "file:",
        !           512:                                "Extension?",
        !           513:                                "Overwrite file?",
        !           514:                        };
        !           515:        static int      last_prompt = -1;
        !           516: 
        !           517:        if (promptno == last_prompt)
        !           518:                move(MOVE_Y, MOVE_X + strlen(names[promptno]) + 1);
        !           519:        else {
        !           520:                move(MOVE_Y, MOVE_X);
        !           521:                if (promptno == MOVEPROMPT)
        !           522:                        standout();
        !           523:                addstr(names[promptno]);
        !           524:                if (promptno == MOVEPROMPT)
        !           525:                        standend();
        !           526:                addch(' ');
        !           527:                last_prompt = promptno;
        !           528:        }
        !           529:        clrtoeol();
        !           530: }
        !           531: 
        !           532: sort(hand)
        !           533: reg CARD       *hand;
        !           534: {
        !           535:        reg CARD        *cp, *tp;
        !           536:        reg CARD        temp;
        !           537: 
        !           538:        cp = hand;
        !           539:        hand += HAND_SZ;
        !           540:        for ( ; cp < &hand[-1]; cp++)
        !           541:                for (tp = cp + 1; tp < hand; tp++)
        !           542:                        if (*cp > *tp) {
        !           543:                                temp = *cp;
        !           544:                                *cp = *tp;
        !           545:                                *tp = temp;
        !           546:                        }
        !           547: }
        !           548: 

unix.superglobalmegacorp.com

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