]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - mille/comp.c
1 /* $NetBSD: comp.c,v 1.4 1995/03/24 05:01:11 cgd Exp $ */
4 * Copyright (c) 1982, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 static char sccsid
[] = "@(#)comp.c 8.1 (Berkeley) 5/31/93";
40 static char rcsid
[] = "$NetBSD: comp.c,v 1.4 1995/03/24 05:01:11 cgd Exp $";
47 * @(#)comp.c 1.1 (Berkeley) 4/1/82
50 # define V_VALUABLE 40
56 register PLAY
*pp
, *op
;
57 register bool foundend
, cango
, canstop
, foundlow
;
58 register unsgn
int i
, count200
, badcount
, nummin
, nummax
, diff
;
59 register int curmin
, curmax
;
60 register CARD safe
, oppos
;
61 int valbuf
[HAND_SZ
], count
[NUM_CARDS
];
64 wmove(Score
, ERR_Y
, ERR_X
); /* get rid of error messages */
73 /* Try for a Coup Forre, and see what we have. */
74 for (i
= 0; i
< NUM_CARDS
; i
++)
76 for (i
= 0; i
< HAND_SZ
; i
++) {
79 case C_STOP
: case C_CRASH
:
80 case C_FLAT
: case C_EMPTY
:
81 if (playit
[i
] = canplay(pp
, op
, card
))
85 if ((playit
[i
] = canplay(pp
, op
, card
))
86 && Numseen
[C_25
] == Numcards
[C_25
]
87 && Numseen
[C_50
] == Numcards
[C_50
])
90 case C_25
: case C_50
: case C_75
:
91 case C_100
: case C_200
:
92 if ((playit
[i
] = canplay(pp
, op
, card
))
93 && pp
->mileage
+ Value
[card
] == End
)
97 playit
[i
] = canplay(pp
, op
, card
);
102 case C_GAS_SAFE
: case C_DRIVE_SAFE
:
103 case C_SPARE_SAFE
: case C_RIGHT_WAY
:
104 if (pp
->battle
== opposite(card
) ||
105 (pp
->speed
== C_LIMIT
&& card
== C_RIGHT_WAY
)) {
118 /* No Coup Forre. Draw to fill hand, then restart, as needed. */
119 if (pp
->hand
[0] == C_INIT
&& Topcard
> Deck
) {
126 fprintf(outf
, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n",
127 cango
, canstop
, safe
);
130 foundend
= !check_ext(TRUE
);
131 for (i
= 0; safe
&& i
< HAND_SZ
; i
++) {
132 if (issafety(pp
->hand
[i
])) {
133 if (onecard(op
) || (foundend
&& cango
&& !canstop
)) {
137 "CALCMOVE: onecard(op) = %d, foundend = %d\n",
138 onecard(op
), foundend
);
145 oppos
= opposite(pp
->hand
[i
]);
146 if (Numseen
[oppos
] == Numcards
[oppos
] &&
147 !(pp
->hand
[i
] == C_RIGHT_WAY
&&
148 Numseen
[C_LIMIT
] != Numcards
[C_LIMIT
]))
151 && (op
->can_go
|| !pp
->can_go
|| Topcard
< Deck
)) {
152 card
= (Topcard
- Deck
) - roll(1, 10);
153 if ((!pp
->mileage
) != (!op
->mileage
))
158 "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n",
161 if (card
< DECK_SZ
/ 4)
168 if (!pp
->can_go
&& !isrepair(pp
->battle
))
169 Numneed
[opposite(pp
->battle
)]++;
171 foundlow
= (cango
|| count
[C_END_LIMIT
] != 0
172 || Numseen
[C_LIMIT
] == Numcards
[C_LIMIT
]
173 || pp
->safety
[S_RIGHT_WAY
] != S_UNKNOWN
);
175 count200
= pp
->nummiles
[C_200
];
182 for (i
= 0; i
< HAND_SZ
; i
++) {
184 if (issafety(card
) || playit
[i
] == (cango
!= 0)) {
187 fprintf(outf
, "CALCMOVE: switch(\"%s\")\n",
191 case C_25
: case C_50
:
192 diff
= End
- pp
->mileage
;
193 /* avoid getting too close */
194 if (Topcard
> Deck
&& cango
&& diff
<= 100
195 && diff
/ Value
[card
] > count
[card
]
196 && (card
== C_25
|| diff
% 50 == 0)) {
197 if (card
== C_50
&& diff
- 50 == 25
206 *value
= (Value
[card
] >> 3);
207 if (pp
->speed
== C_LIMIT
)
212 && (card
== C_50
|| count
[C_50
] == 0)) {
213 *value
= (pp
->mileage
? 10 : 20);
218 if (++count200
> 2) {
222 case C_75
: case C_100
:
223 *value
= (Value
[card
] >> 3);
224 if (pp
->speed
== C_LIMIT
)
229 if (pp
->mileage
+ Value
[card
] > End
)
230 *value
= (End
== 700 ? card
: 0);
231 else if (pp
->mileage
+ Value
[card
] == End
) {
232 *value
= (foundend
? card
: V_VALUABLE
);
237 if (pp
->safety
[S_RIGHT_WAY
] != S_UNKNOWN
)
238 *value
= (pp
->safety
[S_RIGHT_WAY
] ==
240 else if (pp
->speed
== C_LIMIT
&&
241 End
- pp
->mileage
<= 50)
243 else if (pp
->speed
== C_LIMIT
244 || Numseen
[C_LIMIT
] != Numcards
[C_LIMIT
]) {
251 --count
[C_END_LIMIT
];
254 case C_REPAIRS
: case C_SPARE
: case C_GAS
:
255 safe
= safety(card
) - S_CONV
;
256 oppos
= opposite(card
);
257 if (pp
->safety
[safe
] != S_UNKNOWN
)
258 *value
= (pp
->safety
[safe
] ==
260 else if (pp
->battle
!= oppos
261 && (Numseen
[oppos
] == Numcards
[oppos
] ||
262 Numseen
[oppos
] + count
[card
] >
269 *value
= Numcards
[oppos
] * 6;
270 *value
+= Numseen
[card
] -
273 *value
/= (count
[card
]*count
[card
]);
278 if (pp
->safety
[S_RIGHT_WAY
] != S_UNKNOWN
)
279 *value
= (pp
->safety
[S_RIGHT_WAY
] ==
282 && Numgos
+ count
[C_GO
] == Numneed
[C_GO
]) {
287 *value
= Numneed
[C_GO
] * 3;
288 *value
+= (Numseen
[C_GO
] - Numgos
);
289 *value
/= (count
[C_GO
] * count
[C_GO
]);
294 if (op
->mileage
+ 50 >= End
) {
295 *value
= (End
== 700 && !cango
);
298 if (canstop
|| (cango
&& !op
->can_go
))
301 *value
= (pp
->safety
[S_RIGHT_WAY
] !=
308 case C_CRASH
: case C_EMPTY
: case C_FLAT
:
309 safe
= safety(card
) - S_CONV
;
310 oppos
= opposite(card
);
311 *value
= (pp
->safety
[safe
]!=S_UNKNOWN
? 3 : 4);
313 if (op
->safety
[safe
] == S_PLAYED
)
316 *value
*= Numneed
[oppos
] +
318 if (!pp
->mileage
|| foundend
||
321 if (op
->mileage
== 0 || onecard(op
))
323 if (op
->speed
== C_LIMIT
)
326 pp
->safety
[safe
] != S_UNKNOWN
)
329 *value
/= ++badcount
;
333 if (op
->safety
[S_RIGHT_WAY
] == S_PLAYED
)
336 *value
= (pp
->safety
[S_RIGHT_WAY
] !=
338 *value
*= Numcards
[C_STOP
] +
340 if (!pp
->mileage
|| foundend
||
344 *value
/= ++badcount
;
345 if (op
->mileage
== 0)
347 if ((card
== C_LIMIT
&&
348 op
->speed
== C_LIMIT
) ||
351 if (cango
&& pp
->safety
[S_RIGHT_WAY
] !=
356 case C_GAS_SAFE
: case C_DRIVE_SAFE
:
357 case C_SPARE_SAFE
: case C_RIGHT_WAY
:
358 *value
= cango
? 0 : 101;
366 *value
= cango
? 0 : 101;
367 if (card
!= C_INIT
) {
368 if (*value
>= curmax
) {
372 if (*value
<= curmin
) {
379 mvprintw(i
+ 6, 2, "%3d %-14s", *value
,
380 C_name
[pp
->hand
[i
]]);
384 if (!pp
->can_go
&& !isrepair(pp
->battle
))
385 Numneed
[opposite(pp
->battle
)]++;
388 mvaddstr(MOVE_Y
+ 1, MOVE_X
, "PLAY\n");
393 if (issafety(pp
->hand
[nummin
])) { /* NEVER discard a safety */
397 mvaddstr(MOVE_Y
+ 1, MOVE_X
, "DISCARD\n");
398 Movetype
= M_DISCARD
;
401 mvprintw(MOVE_Y
+ 2, MOVE_X
, "%16s", C_name
[pp
->hand
[Card_no
]]);
405 * Return true if the given player could conceivably win with his next card.
410 register CARD bat
, spd
, card
;
415 if (pp
->can_go
|| ((isrepair(bat
) || bat
== C_STOP
|| spd
== C_LIMIT
) &&
416 Numseen
[S_RIGHT_WAY
] != 0) ||
417 bat
>= 0 && Numseen
[safety(bat
)] != 0)
418 switch (End
- pp
->mileage
) {
420 if (pp
->nummiles
[C_200
] == 2)
427 card
= (End
- pp
->mileage
== 75 ? C_75
: C_100
);
429 return Numseen
[S_RIGHT_WAY
] == 0;
433 card
= (End
- pp
->mileage
== 25 ? C_25
: C_50
);
434 return Numseen
[card
] != Numcards
[card
];
439 canplay(pp
, op
, card
)
440 register PLAY
*pp
, *op
;
445 if (pp
->nummiles
[C_200
] == 2)
448 case C_75
: case C_100
:
449 if (pp
->speed
== C_LIMIT
)
453 if (pp
->mileage
+ Value
[card
] > End
)
460 case C_EMPTY
: case C_FLAT
: case C_CRASH
:
462 if (op
->can_go
&& op
->safety
[safety(card
) - S_CONV
] != S_PLAYED
)
466 if (op
->speed
!= C_LIMIT
&&
467 op
->safety
[S_RIGHT_WAY
] != S_PLAYED
&&
468 op
->mileage
+ 50 < End
)
471 case C_GAS
: case C_SPARE
: case C_REPAIRS
:
472 if (pp
->battle
== opposite(card
))
477 (isrepair(pp
->battle
) || pp
->battle
== C_STOP
))
481 if (pp
->speed
== C_LIMIT
)