|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.