Annotation of researchv10no/games/mille/move.c, revision 1.1

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

unix.superglobalmegacorp.com

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