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: }

Defined functions

account defined in line 445; used 4 times
check_go defined in line 121; used 1 times
domove defined in line 22; used 1 times
getmove defined in line 294; used 3 times
haspicked defined in line 426; used 3 times
playcard defined in line 147; used 1 times
  • in line 60
prompt defined in line 470; used 4 times
sort defined in line 501; used 2 times

Defined variables

Movenames defined in line 18; never used

Defined macros

CTRL defined in line 16; used 2 times
_tty defined in line 8; never used
Last modified: 1986-01-23
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1803
Valid CSS Valid XHTML 1.0 Strict