|
|
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.