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

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

unix.superglobalmegacorp.com

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