|
|
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: reg CARD card; ! 12: reg int *value; ! 13: reg PLAY *pp, *op; ! 14: reg bool foundend, cango, canstop, foundlow; ! 15: reg unsgn int i, count200, badcount, nummin, nummax, diff; ! 16: reg int curmin, curmax; ! 17: reg 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", cango, canstop, safe); ! 77: if (foundend) ! 78: foundend = !check_ext(TRUE); ! 79: for (i = 0; safe && i < HAND_SZ; i++) { ! 80: if (issafety(pp->hand[i])) { ! 81: if (onecard(op) || (foundend && cango && !canstop)) { ! 82: if (Debug) ! 83: fprintf(outf, "CALCMOVE: onecard(op) = %d, foundend = %d\n", onecard(op), foundend); ! 84: playsafe: ! 85: Movetype = M_PLAY; ! 86: Card_no = i; ! 87: return; ! 88: } ! 89: oppos = opposite(pp->hand[i]); ! 90: if (Numseen[oppos] == Numcards[oppos]) ! 91: goto playsafe; ! 92: else if (!cango ! 93: && (op->can_go || !pp->can_go || Topcard < Deck)) { ! 94: card = (Topcard - Deck) - roll(1, 10); ! 95: if ((!pp->mileage) != (!op->mileage)) ! 96: card -= 7; ! 97: if (Debug) ! 98: fprintf(outf, "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n", card, DECK_SZ / 4); ! 99: if (card < DECK_SZ / 4) ! 100: goto playsafe; ! 101: } ! 102: safe--; ! 103: playit[i] = cango; ! 104: } ! 105: } ! 106: if (!pp->can_go && !isrepair(pp->battle)) ! 107: Numneed[opposite(pp->battle)]++; ! 108: redoit: ! 109: foundlow = (cango || count[C_END_LIMIT] != 0 ! 110: || Numseen[C_LIMIT] == Numcards[C_LIMIT] ! 111: || pp->safety[S_RIGHT_WAY] != S_UNKNOWN); ! 112: foundend = FALSE; ! 113: count200 = pp->nummiles[C_200]; ! 114: badcount = 0; ! 115: curmax = -1; ! 116: curmin = 101; ! 117: nummin = -1; ! 118: nummax = -1; ! 119: value = valbuf; ! 120: for (i = 0; i < HAND_SZ; i++) { ! 121: card = pp->hand[i]; ! 122: if (issafety(card) || playit[i] == (cango != 0)) { ! 123: if (Debug) ! 124: fprintf(outf, "CALCMOVE: switch(\"%s\")\n", C_name[card]); ! 125: switch (card) { ! 126: case C_25: case C_50: ! 127: diff = End - pp->mileage; ! 128: /* avoid getting too close */ ! 129: if (Topcard > Deck && cango && diff <= 100 ! 130: && diff / Value[card] > count[card] ! 131: && (card == C_25 || diff % 50 == 0)) { ! 132: if (card == C_50 && diff - 50 == 25 ! 133: && count[C_25] > 0) ! 134: goto okay; ! 135: *value = 0; ! 136: if (--cango <= 0) ! 137: goto redoit; ! 138: break; ! 139: } ! 140: okay: ! 141: *value = (Value[card] >> 3); ! 142: if (pp->speed == C_LIMIT) ! 143: ++*value; ! 144: else ! 145: --*value; ! 146: if (!foundlow ! 147: && (card == C_50 || count[C_50] == 0)) { ! 148: *value = (pp->mileage ? 10 : 20); ! 149: foundlow = TRUE; ! 150: } ! 151: goto miles; ! 152: case C_200: ! 153: if (++count200 > 2) { ! 154: *value = 0; ! 155: break; ! 156: } ! 157: case C_75: case C_100: ! 158: *value = (Value[card] >> 3); ! 159: if (pp->speed == C_LIMIT) ! 160: --*value; ! 161: else ! 162: ++*value; ! 163: miles: ! 164: if (pp->mileage + Value[card] > End) ! 165: *value = (End == 700 ? card : 0); ! 166: else if (pp->mileage + Value[card] == End) { ! 167: *value = (foundend ? card : V_VALUABLE); ! 168: foundend = TRUE; ! 169: } ! 170: break; ! 171: case C_END_LIMIT: ! 172: if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN) ! 173: *value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 1); ! 174: else if (pp->speed == C_LIMIT && End - pp->mileage <= 50) ! 175: *value = 1; ! 176: else if (pp->speed == C_LIMIT ! 177: || Numseen[C_LIMIT] != Numcards[C_LIMIT]) { ! 178: safe = S_RIGHT_WAY; ! 179: oppos = C_LIMIT; ! 180: goto repair; ! 181: } ! 182: else { ! 183: *value = 0; ! 184: --count[C_END_LIMIT]; ! 185: } ! 186: break; ! 187: case C_REPAIRS: case C_SPARE: case C_GAS: ! 188: safe = safety(card) - S_CONV; ! 189: oppos = opposite(card); ! 190: if (pp->safety[safe] != S_UNKNOWN) ! 191: *value = (pp->safety[safe] == S_PLAYED ? -1 : 1); ! 192: else if (pp->battle != oppos ! 193: && (Numseen[oppos] == Numcards[oppos] || Numseen[oppos] + count[card] > Numcards[oppos])) { ! 194: *value = 0; ! 195: --count[card]; ! 196: } ! 197: else { ! 198: repair: ! 199: *value = Numcards[oppos] * 6; ! 200: *value += (Numseen[card] - Numseen[oppos]); ! 201: if (!cango) ! 202: *value /= (count[card]*count[card]); ! 203: count[card]--; ! 204: } ! 205: break; ! 206: case C_GO: ! 207: if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN) ! 208: *value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 2); ! 209: else if (pp->can_go ! 210: && Numgos + count[C_GO] == Numneed[C_GO]) { ! 211: *value = 0; ! 212: --count[C_GO]; ! 213: } ! 214: else { ! 215: *value = Numneed[C_GO] * 3; ! 216: *value += (Numseen[C_GO] - Numgos); ! 217: *value /= (count[C_GO] * count[C_GO]); ! 218: count[C_GO]--; ! 219: } ! 220: break; ! 221: case C_LIMIT: ! 222: if (op->mileage + 50 >= End) { ! 223: *value = (End == 700 && !cango); ! 224: break; ! 225: } ! 226: if (canstop || (cango && !op->can_go)) ! 227: *value = 1; ! 228: else { ! 229: *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 2 : 3); ! 230: safe = S_RIGHT_WAY; ! 231: oppos = C_END_LIMIT; ! 232: goto normbad; ! 233: } ! 234: break; ! 235: case C_CRASH: case C_EMPTY: case C_FLAT: ! 236: safe = safety(card) - S_CONV; ! 237: oppos = opposite(card); ! 238: *value = (pp->safety[safe]!=S_UNKNOWN ? 3 : 4); ! 239: normbad: ! 240: if (op->safety[safe] == S_PLAYED) ! 241: *value = -1; ! 242: else { ! 243: *value *= (Numneed[oppos] + Numseen[oppos] + 2); ! 244: if (!pp->mileage || foundend || onecard(op)) ! 245: *value += 5; ! 246: if (op->mileage == 0 || onecard(op)) ! 247: *value += 5; ! 248: if (op->speed == C_LIMIT) ! 249: *value -= 3; ! 250: if (cango && pp->safety[safe] != S_UNKNOWN) ! 251: *value += 3; ! 252: if (!cango) ! 253: *value /= ++badcount; ! 254: } ! 255: break; ! 256: case C_STOP: ! 257: if (op->safety[S_RIGHT_WAY] == S_PLAYED) ! 258: *value = -1; ! 259: else { ! 260: *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 3 : 4); ! 261: *value *= (Numcards[C_STOP] + Numseen[C_GO]); ! 262: if (!pp->mileage || foundend || onecard(op)) ! 263: *value += 5; ! 264: if (!cango) ! 265: *value /= ++badcount; ! 266: if (op->mileage == 0) ! 267: *value += 5; ! 268: if ((card == C_LIMIT ! 269: && op->speed == C_LIMIT) || (!op->can_go)) ! 270: *value -= 5; ! 271: if (cango && pp->safety[S_RIGHT_WAY] != S_UNKNOWN) ! 272: *value += 5; ! 273: } ! 274: break; ! 275: case C_GAS_SAFE: case C_DRIVE_SAFE: ! 276: case C_SPARE_SAFE: case C_RIGHT_WAY: ! 277: *value = cango ? 0 : 101; ! 278: break; ! 279: case C_INIT: ! 280: *value = 0; ! 281: } ! 282: } ! 283: else ! 284: *value = cango ? 0 : 101; ! 285: if (card != C_INIT) { ! 286: if (*value >= curmax) { ! 287: nummax = i; ! 288: curmax = *value; ! 289: } ! 290: if (*value <= curmin) { ! 291: nummin = i; ! 292: curmin = *value; ! 293: } ! 294: } ! 295: if (Debug) ! 296: mvprintw(i+6,2,"%3d %-14s",*value,C_name[pp->hand[i]]); ! 297: value++; ! 298: } ! 299: if (!pp->can_go && !isrepair(pp->battle)) ! 300: Numneed[opposite(pp->battle)]++; ! 301: if (cango) { ! 302: mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n"); ! 303: if (Debug) ! 304: getmove(); ! 305: if (!Debug || Movetype == M_DRAW) { ! 306: Movetype = M_PLAY; ! 307: Card_no = nummax; ! 308: } ! 309: } ! 310: else { ! 311: mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n"); ! 312: if (Debug) ! 313: getmove(); ! 314: if (!Debug || Movetype == M_DRAW) { ! 315: Movetype = M_DISCARD; ! 316: Card_no = nummin; ! 317: } ! 318: } ! 319: mvprintw(MOVE_Y + 2, MOVE_X, "%16s", C_name[pp->hand[Card_no]]); ! 320: } ! 321: ! 322: onecard(pp) ! 323: reg PLAY *pp; { ! 324: ! 325: reg CARD bat, spd, card; ! 326: ! 327: bat = pp->battle; ! 328: spd = pp->speed; ! 329: card = -1; ! 330: if (pp->can_go || ((isrepair(bat) || bat == C_STOP ! 331: || spd == C_LIMIT) && Numseen[S_RIGHT_WAY] != 0) ! 332: || Numseen[safety(bat)] != 0) ! 333: switch (End - pp->mileage) { ! 334: case 200: ! 335: if (pp->nummiles[C_200] == 2) ! 336: return FALSE; ! 337: card = C_200; ! 338: case 100: ! 339: case 75: ! 340: if (card == -1) ! 341: card = (End - pp->mileage == 75 ? C_75 : C_100); ! 342: if (spd == C_LIMIT) ! 343: return Numseen[S_RIGHT_WAY] == 0; ! 344: case 50: ! 345: case 25: ! 346: if (card == -1) ! 347: card = (End - pp->mileage == 25 ? C_25 : C_50); ! 348: return Numseen[card] != Numcards[card]; ! 349: } ! 350: return FALSE; ! 351: } ! 352: ! 353: canplay(pp, op, card) ! 354: reg PLAY *pp, *op; ! 355: reg CARD card; { ! 356: ! 357: switch (card) { ! 358: case C_200: ! 359: if (pp->nummiles[C_200] == 2) ! 360: break; ! 361: case C_75: case C_100: ! 362: if (pp->speed == C_LIMIT) ! 363: break; ! 364: case C_50: ! 365: if (pp->mileage + Value[card] > End) ! 366: break; ! 367: case C_25: ! 368: if (pp->can_go) ! 369: return TRUE; ! 370: break; ! 371: case C_EMPTY: case C_FLAT: case C_CRASH: ! 372: case C_STOP: ! 373: if (op->can_go && op->safety[safety(card) - S_CONV] != S_PLAYED) ! 374: return TRUE; ! 375: break; ! 376: case C_LIMIT: ! 377: if (op->speed != C_LIMIT && op->safety[S_RIGHT_WAY] != S_PLAYED ! 378: && op->mileage + 50 < End) ! 379: return TRUE; ! 380: break; ! 381: case C_GAS: case C_SPARE: case C_REPAIRS: ! 382: if (pp->battle == opposite(card)) ! 383: return TRUE; ! 384: break; ! 385: case C_GO: ! 386: if (!pp->can_go ! 387: && (isrepair(pp->battle) || pp->battle == C_STOP)) ! 388: return TRUE; ! 389: break; ! 390: case C_END_LIMIT: ! 391: if (pp->speed == C_LIMIT) ! 392: return TRUE; ! 393: } ! 394: return FALSE; ! 395: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.