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

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

unix.superglobalmegacorp.com

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