1: # include   "mille.h"
   2: 
   3: /*
   4:  * @(#)comp.c	1.1 (Berkeley) 4/1/82
   5:  */
   6: 
   7: # define    V_VALUABLE  40
   8: 
   9: calcmove()
  10: {
  11:     register CARD       card;
  12:     register int        *value;
  13:     register PLAY       *pp, *op;
  14:     register bool       foundend, cango, canstop, foundlow;
  15:     register unsgn int  i, count200, badcount, nummin, nummax, diff;
  16:     register int        curmin, curmax;
  17:     register CARD       safe, oppos;
  18:     int         valbuf[HAND_SZ], count[NUM_CARDS];
  19:     bool            playit[HAND_SZ];
  20: 
  21:     wmove(Score, ERR_Y, ERR_X); /* get rid of error messages	*/
  22:     wclrtoeol(Score);
  23:     pp = &Player[COMP];
  24:     op = &Player[PLAYER];
  25:     safe = 0;
  26:     cango = 0;
  27:     canstop = FALSE;
  28:     foundend = FALSE;
  29:     for (i = 0; i < NUM_CARDS; i++)
  30:         count[i] = 0;
  31:     for (i = 0; i < HAND_SZ; i++) {
  32:         card = pp->hand[i];
  33:         switch (card) {
  34:           case C_STOP:  case C_CRASH:
  35:           case C_FLAT:  case C_EMPTY:
  36:             if (playit[i] = canplay(pp, op, card))
  37:                 canstop = TRUE;
  38:             goto norm;
  39:           case C_LIMIT:
  40:             if ((playit[i] = canplay(pp, op, card))
  41:                 && Numseen[C_25] == Numcards[C_25]
  42:                 && Numseen[C_50] == Numcards[C_50])
  43:                 canstop = TRUE;
  44:             goto norm;
  45:           case C_25:    case C_50:  case C_75:
  46:           case C_100:   case C_200:
  47:             if ((playit[i] = canplay(pp, op, card))
  48:                 && pp->mileage + Value[card] == End)
  49:                 foundend = TRUE;
  50:             goto norm;
  51:           default:
  52:             playit[i] = canplay(pp, op, card);
  53: norm:
  54:             if (playit[i])
  55:                 ++cango;
  56:             break;
  57:           case C_GAS_SAFE:  case C_DRIVE_SAFE:
  58:           case C_SPARE_SAFE:    case C_RIGHT_WAY:
  59:             if (pp->battle == opposite(card) ||
  60:                 (pp->speed == C_LIMIT && card == C_RIGHT_WAY)) {
  61:                 Movetype = M_PLAY;
  62:                 Card_no = i;
  63:                 return;
  64:             }
  65:             ++safe;
  66:             playit[i] = TRUE;
  67:             break;
  68:         }
  69:         ++count[card];
  70:     }
  71:     if (pp->hand[0] == C_INIT && Topcard > Deck) {
  72:         Movetype = M_DRAW;
  73:         return;
  74:     }
  75:     if (Debug)
  76:         fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n",
  77:             cango, canstop, safe);
  78:     if (foundend)
  79:         foundend = !check_ext(TRUE);
  80:     for (i = 0; safe && i < HAND_SZ; i++) {
  81:         if (issafety(pp->hand[i])) {
  82:             if (onecard(op) || (foundend && cango && !canstop)) {
  83:                 if (Debug)
  84:                     fprintf(outf,
  85:                         "CALCMOVE: onecard(op) = %d, foundend = %d\n",
  86:                         onecard(op), foundend);
  87: playsafe:
  88:                 Movetype = M_PLAY;
  89:                 Card_no = i;
  90:                 return;
  91:             }
  92:             oppos = opposite(pp->hand[i]);
  93:             if (Numseen[oppos] == Numcards[oppos] &&
  94:                 !(pp->hand[i] == C_RIGHT_WAY &&
  95:                   Numseen[C_LIMIT] != Numcards[C_LIMIT]))
  96:                 goto playsafe;
  97:             else if (!cango
  98:                 && (op->can_go || !pp->can_go || Topcard < Deck)) {
  99:                 card = (Topcard - Deck) - roll(1, 10);
 100:                 if ((!pp->mileage) != (!op->mileage))
 101:                     card -= 7;
 102:                 if (Debug)
 103:                     fprintf(outf,
 104:                         "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n",
 105:                         card, DECK_SZ / 4);
 106:                 if (card < DECK_SZ / 4)
 107:                     goto playsafe;
 108:             }
 109:             safe--;
 110:             playit[i] = cango;
 111:         }
 112:     }
 113:     if (!pp->can_go && !isrepair(pp->battle))
 114:         Numneed[opposite(pp->battle)]++;
 115: redoit:
 116:     foundlow = (cango || count[C_END_LIMIT] != 0
 117:               || Numseen[C_LIMIT] == Numcards[C_LIMIT]
 118:               || pp->safety[S_RIGHT_WAY] != S_UNKNOWN);
 119:     foundend = FALSE;
 120:     count200 = pp->nummiles[C_200];
 121:     badcount = 0;
 122:     curmax = -1;
 123:     curmin = 101;
 124:     nummin = -1;
 125:     nummax = -1;
 126:     value = valbuf;
 127:     for (i = 0; i < HAND_SZ; i++) {
 128:         card = pp->hand[i];
 129:         if (issafety(card) || playit[i] == (cango != 0)) {
 130:             if (Debug)
 131:                 fprintf(outf, "CALCMOVE: switch(\"%s\")\n",
 132:                     C_name[card]);
 133:             switch (card) {
 134:               case C_25:    case C_50:
 135:                 diff = End - pp->mileage;
 136:                 /* avoid getting too close */
 137:                 if (Topcard > Deck && cango && diff <= 100
 138:                     && diff / Value[card] > count[card]
 139:                     && (card == C_25 || diff % 50 == 0)) {
 140:                     if (card == C_50 && diff - 50 == 25
 141:                         && count[C_25] > 0)
 142:                         goto okay;
 143:                     *value = 0;
 144:                     if (--cango <= 0)
 145:                         goto redoit;
 146:                     break;
 147:                 }
 148: okay:
 149:                 *value = (Value[card] >> 3);
 150:                 if (pp->speed == C_LIMIT)
 151:                     ++*value;
 152:                 else
 153:                     --*value;
 154:                 if (!foundlow
 155:                    && (card == C_50 || count[C_50] == 0)) {
 156:                     *value = (pp->mileage ? 10 : 20);
 157:                     foundlow = TRUE;
 158:                 }
 159:                 goto miles;
 160:               case C_200:
 161:                 if (++count200 > 2) {
 162:                     *value = 0;
 163:                     break;
 164:                 }
 165:               case C_75:    case C_100:
 166:                 *value = (Value[card] >> 3);
 167:                 if (pp->speed == C_LIMIT)
 168:                     --*value;
 169:                 else
 170:                     ++*value;
 171: miles:
 172:                 if (pp->mileage + Value[card] > End)
 173:                     *value = (End == 700 ? card : 0);
 174:                 else if (pp->mileage + Value[card] == End) {
 175:                     *value = (foundend ? card : V_VALUABLE);
 176:                     foundend = TRUE;
 177:                 }
 178:                 break;
 179:               case C_END_LIMIT:
 180:                 if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
 181:                     *value = (pp->safety[S_RIGHT_WAY] ==
 182:                           S_PLAYED ? -1 : 1);
 183:                 else if (pp->speed == C_LIMIT &&
 184:                      End - pp->mileage <= 50)
 185:                     *value = 1;
 186:                 else if (pp->speed == C_LIMIT
 187:                     || Numseen[C_LIMIT] != Numcards[C_LIMIT]) {
 188:                     safe = S_RIGHT_WAY;
 189:                     oppos = C_LIMIT;
 190:                     goto repair;
 191:                 }
 192:                 else {
 193:                     *value = 0;
 194:                     --count[C_END_LIMIT];
 195:                 }
 196:                 break;
 197:               case C_REPAIRS:   case C_SPARE:   case C_GAS:
 198:                 safe = safety(card) - S_CONV;
 199:                 oppos = opposite(card);
 200:                 if (pp->safety[safe] != S_UNKNOWN)
 201:                     *value = (pp->safety[safe] ==
 202:                           S_PLAYED ? -1 : 1);
 203:                 else if (pp->battle != oppos
 204:                     && (Numseen[oppos] == Numcards[oppos] ||
 205:                     Numseen[oppos] + count[card] >
 206:                     Numcards[oppos])) {
 207:                     *value = 0;
 208:                     --count[card];
 209:                 }
 210:                 else {
 211: repair:
 212:                     *value = Numcards[oppos] * 6;
 213:                     *value += Numseen[card] -
 214:                           Numseen[oppos];
 215:                     if (!cango)
 216:                         *value /= (count[card]*count[card]);
 217:                     count[card]--;
 218:                 }
 219:                 break;
 220:               case C_GO:
 221:                 if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
 222:                     *value = (pp->safety[S_RIGHT_WAY] ==
 223:                           S_PLAYED ? -1 : 2);
 224:                 else if (pp->can_go
 225:                  && Numgos + count[C_GO] == Numneed[C_GO]) {
 226:                     *value = 0;
 227:                     --count[C_GO];
 228:                 }
 229:                 else {
 230:                     *value = Numneed[C_GO] * 3;
 231:                     *value += (Numseen[C_GO] - Numgos);
 232:                     *value /= (count[C_GO] * count[C_GO]);
 233:                     count[C_GO]--;
 234:                 }
 235:                 break;
 236:               case C_LIMIT:
 237:                 if (op->mileage + 50 >= End) {
 238:                     *value = (End == 700 && !cango);
 239:                     break;
 240:                 }
 241:                 if (canstop || (cango && !op->can_go))
 242:                     *value = 1;
 243:                 else {
 244:                     *value = (pp->safety[S_RIGHT_WAY] !=
 245:                           S_UNKNOWN ? 2 : 3);
 246:                     safe = S_RIGHT_WAY;
 247:                     oppos = C_END_LIMIT;
 248:                     goto normbad;
 249:                 }
 250:                 break;
 251:               case C_CRASH: case C_EMPTY:   case C_FLAT:
 252:                 safe = safety(card) - S_CONV;
 253:                 oppos = opposite(card);
 254:                 *value = (pp->safety[safe]!=S_UNKNOWN ? 3 : 4);
 255: normbad:
 256:                 if (op->safety[safe] == S_PLAYED)
 257:                     *value = -1;
 258:                 else {
 259:                     *value *= Numneed[oppos] +
 260:                           Numseen[oppos] + 2;
 261:                     if (!pp->mileage || foundend ||
 262:                         onecard(op))
 263:                         *value += 5;
 264:                     if (op->mileage == 0 || onecard(op))
 265:                         *value += 5;
 266:                     if (op->speed == C_LIMIT)
 267:                         *value -= 3;
 268:                     if (cango &&
 269:                         pp->safety[safe] != S_UNKNOWN)
 270:                         *value += 3;
 271:                     if (!cango)
 272:                         *value /= ++badcount;
 273:                 }
 274:                 break;
 275:               case C_STOP:
 276:                 if (op->safety[S_RIGHT_WAY] == S_PLAYED)
 277:                     *value = -1;
 278:                 else {
 279:                     *value = (pp->safety[S_RIGHT_WAY] !=
 280:                           S_UNKNOWN ? 3 : 4);
 281:                     *value *= Numcards[C_STOP] +
 282:                           Numseen[C_GO];
 283:                     if (!pp->mileage || foundend ||
 284:                         onecard(op))
 285:                         *value += 5;
 286:                     if (!cango)
 287:                         *value /= ++badcount;
 288:                     if (op->mileage == 0)
 289:                         *value += 5;
 290:                     if ((card == C_LIMIT &&
 291:                          op->speed == C_LIMIT) ||
 292:                         !op->can_go)
 293:                         *value -= 5;
 294:                     if (cango && pp->safety[S_RIGHT_WAY] !=
 295:                              S_UNKNOWN)
 296:                         *value += 5;
 297:                 }
 298:                 break;
 299:               case C_GAS_SAFE:  case C_DRIVE_SAFE:
 300:               case C_SPARE_SAFE:    case C_RIGHT_WAY:
 301:                 *value = cango ? 0 : 101;
 302:                 break;
 303:               case C_INIT:
 304:                 *value = 0;
 305:                 break;
 306:             }
 307:         }
 308:         else
 309:             *value = cango ? 0 : 101;
 310:         if (card != C_INIT) {
 311:             if (*value >= curmax) {
 312:                 nummax = i;
 313:                 curmax = *value;
 314:             }
 315:             if (*value <= curmin) {
 316:                 nummin = i;
 317:                 curmin = *value;
 318:             }
 319:         }
 320:         if (Debug)
 321:             mvprintw(i + 6, 2, "%3d %-14s", *value,
 322:                  C_name[pp->hand[i]]);
 323:         value++;
 324:     }
 325:     if (!pp->can_go && !isrepair(pp->battle))
 326:         Numneed[opposite(pp->battle)]++;
 327:     if (cango) {
 328: play_it:
 329:         mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n");
 330:         if (Debug)
 331:             getmove();
 332:         if (!Debug || Movetype == M_DRAW) {
 333:             Movetype = M_PLAY;
 334:             Card_no = nummax;
 335:         }
 336:     }
 337:     else {
 338:         if (issafety(pp->hand[nummin])) { /* NEVER discard a safety */
 339:             nummax = nummin;
 340:             goto play_it;
 341:         }
 342:         mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n");
 343:         if (Debug)
 344:             getmove();
 345:         if (!Debug || Movetype == M_DRAW) {
 346:             Movetype = M_DISCARD;
 347:             Card_no = nummin;
 348:         }
 349:     }
 350:     mvprintw(MOVE_Y + 2, MOVE_X, "%16s", C_name[pp->hand[Card_no]]);
 351: }
 352: 
 353: onecard(pp)
 354: register PLAY   *pp;
 355: {
 356:     register CARD   bat, spd, card;
 357: 
 358:     bat = pp->battle;
 359:     spd = pp->speed;
 360:     card = -1;
 361:     if (pp->can_go || ((isrepair(bat) || bat == C_STOP || spd == C_LIMIT) &&
 362:                Numseen[S_RIGHT_WAY] != 0) ||
 363:         Numseen[safety(bat)] != 0)
 364:         switch (End - pp->mileage) {
 365:           case 200:
 366:             if (pp->nummiles[C_200] == 2)
 367:                 return FALSE;
 368:             card = C_200;
 369:             /* FALLTHROUGH */
 370:           case 100:
 371:           case 75:
 372:             if (card == -1)
 373:                 card = (End - pp->mileage == 75 ? C_75 : C_100);
 374:             if (spd == C_LIMIT)
 375:                 return Numseen[S_RIGHT_WAY] == 0;
 376:           case 50:
 377:           case 25:
 378:             if (card == -1)
 379:                 card = (End - pp->mileage == 25 ? C_25 : C_50);
 380:             return Numseen[card] != Numcards[card];
 381:         }
 382:     return FALSE;
 383: }
 384: 
 385: canplay(pp, op, card)
 386: register PLAY   *pp, *op;
 387: register CARD   card;
 388: {
 389:     switch (card) {
 390:       case C_200:
 391:         if (pp->nummiles[C_200] == 2)
 392:             break;
 393:         /* FALLTHROUGH */
 394:       case C_75:    case C_100:
 395:         if (pp->speed == C_LIMIT)
 396:             break;
 397:         /* FALLTHROUGH */
 398:       case C_50:
 399:         if (pp->mileage + Value[card] > End)
 400:             break;
 401:         /* FALLTHROUGH */
 402:       case C_25:
 403:         if (pp->can_go)
 404:             return TRUE;
 405:         break;
 406:       case C_EMPTY: case C_FLAT:    case C_CRASH:
 407:       case C_STOP:
 408:         if (op->can_go && op->safety[safety(card) - S_CONV] != S_PLAYED)
 409:             return TRUE;
 410:         break;
 411:       case C_LIMIT:
 412:         if (op->speed != C_LIMIT &&
 413:             op->safety[S_RIGHT_WAY] != S_PLAYED &&
 414:             op->mileage + 50 < End)
 415:             return TRUE;
 416:         break;
 417:       case C_GAS:   case C_SPARE:   case C_REPAIRS:
 418:         if (pp->battle == opposite(card))
 419:             return TRUE;
 420:         break;
 421:       case C_GO:
 422:         if (!pp->can_go &&
 423:             (isrepair(pp->battle) || pp->battle == C_STOP))
 424:             return TRUE;
 425:         break;
 426:       case C_END_LIMIT:
 427:         if (pp->speed == C_LIMIT)
 428:             return TRUE;
 429:     }
 430:     return FALSE;
 431: }

Defined functions

calcmove defined in line 9; used 1 times
canplay defined in line 385; used 6 times
onecard defined in line 353; used 6 times

Defined macros

V_VALUABLE defined in line 7; used 1 times
Last modified: 1985-06-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1612
Valid CSS Valid XHTML 1.0 Strict