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