* Copyright (c) 1982 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)comp.c 5.3 (Berkeley) %G%";
* @(#)comp.c 1.1 (Berkeley) 4/1/82
register bool foundend
, cango
, canstop
, foundlow
;
register unsgn
int i
, count200
, badcount
, nummin
, nummax
, diff
;
register int curmin
, curmax
;
register CARD safe
, oppos
;
int valbuf
[HAND_SZ
], count
[NUM_CARDS
];
wmove(Score
, ERR_Y
, ERR_X
); /* get rid of error messages */
for (i
= 0; i
< NUM_CARDS
; i
++)
for (i
= 0; i
< HAND_SZ
; i
++) {
case C_STOP
: case C_CRASH
:
case C_FLAT
: case C_EMPTY
:
if (playit
[i
] = canplay(pp
, op
, card
))
if ((playit
[i
] = canplay(pp
, op
, card
))
&& Numseen
[C_25
] == Numcards
[C_25
]
&& Numseen
[C_50
] == Numcards
[C_50
])
case C_25
: case C_50
: case C_75
:
if ((playit
[i
] = canplay(pp
, op
, card
))
&& pp
->mileage
+ Value
[card
] == End
)
playit
[i
] = canplay(pp
, op
, card
);
case C_GAS_SAFE
: case C_DRIVE_SAFE
:
case C_SPARE_SAFE
: case C_RIGHT_WAY
:
if (pp
->battle
== opposite(card
) ||
(pp
->speed
== C_LIMIT
&& card
== C_RIGHT_WAY
)) {
if (pp
->hand
[0] == C_INIT
&& Topcard
> Deck
) {
fprintf(outf
, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n",
foundend
= !check_ext(TRUE
);
for (i
= 0; safe
&& i
< HAND_SZ
; i
++) {
if (issafety(pp
->hand
[i
])) {
if (onecard(op
) || (foundend
&& cango
&& !canstop
)) {
"CALCMOVE: onecard(op) = %d, foundend = %d\n",
oppos
= opposite(pp
->hand
[i
]);
if (Numseen
[oppos
] == Numcards
[oppos
] &&
!(pp
->hand
[i
] == C_RIGHT_WAY
&&
Numseen
[C_LIMIT
] != Numcards
[C_LIMIT
]))
&& (op
->can_go
|| !pp
->can_go
|| Topcard
< Deck
)) {
card
= (Topcard
- Deck
) - roll(1, 10);
if ((!pp
->mileage
) != (!op
->mileage
))
"CALCMOVE: card = %d, DECK_SZ / 4 = %d\n",
if (!pp
->can_go
&& !isrepair(pp
->battle
))
Numneed
[opposite(pp
->battle
)]++;
foundlow
= (cango
|| count
[C_END_LIMIT
] != 0
|| Numseen
[C_LIMIT
] == Numcards
[C_LIMIT
]
|| pp
->safety
[S_RIGHT_WAY
] != S_UNKNOWN
);
count200
= pp
->nummiles
[C_200
];
for (i
= 0; i
< HAND_SZ
; i
++) {
if (issafety(card
) || playit
[i
] == (cango
!= 0)) {
fprintf(outf
, "CALCMOVE: switch(\"%s\")\n",
diff
= End
- pp
->mileage
;
/* avoid getting too close */
if (Topcard
> Deck
&& cango
&& diff
<= 100
&& diff
/ Value
[card
] > count
[card
]
&& (card
== C_25
|| diff
% 50 == 0)) {
if (card
== C_50
&& diff
- 50 == 25
*value
= (Value
[card
] >> 3);
if (pp
->speed
== C_LIMIT
)
&& (card
== C_50
|| count
[C_50
] == 0)) {
*value
= (pp
->mileage
? 10 : 20);
*value
= (Value
[card
] >> 3);
if (pp
->speed
== C_LIMIT
)
if (pp
->mileage
+ Value
[card
] > End
)
*value
= (End
== 700 ? card
: 0);
else if (pp
->mileage
+ Value
[card
] == End
) {
*value
= (foundend
? card
: V_VALUABLE
);
if (pp
->safety
[S_RIGHT_WAY
] != S_UNKNOWN
)
*value
= (pp
->safety
[S_RIGHT_WAY
] ==
else if (pp
->speed
== C_LIMIT
&&
else if (pp
->speed
== C_LIMIT
|| Numseen
[C_LIMIT
] != Numcards
[C_LIMIT
]) {
case C_REPAIRS
: case C_SPARE
: case C_GAS
:
safe
= safety(card
) - S_CONV
;
if (pp
->safety
[safe
] != S_UNKNOWN
)
*value
= (pp
->safety
[safe
] ==
else if (pp
->battle
!= oppos
&& (Numseen
[oppos
] == Numcards
[oppos
] ||
Numseen
[oppos
] + count
[card
] >
*value
= Numcards
[oppos
] * 6;
*value
+= Numseen
[card
] -
*value
/= (count
[card
]*count
[card
]);
if (pp
->safety
[S_RIGHT_WAY
] != S_UNKNOWN
)
*value
= (pp
->safety
[S_RIGHT_WAY
] ==
&& Numgos
+ count
[C_GO
] == Numneed
[C_GO
]) {
*value
= Numneed
[C_GO
] * 3;
*value
+= (Numseen
[C_GO
] - Numgos
);
*value
/= (count
[C_GO
] * count
[C_GO
]);
if (op
->mileage
+ 50 >= End
) {
*value
= (End
== 700 && !cango
);
if (canstop
|| (cango
&& !op
->can_go
))
*value
= (pp
->safety
[S_RIGHT_WAY
] !=
case C_CRASH
: case C_EMPTY
: case C_FLAT
:
safe
= safety(card
) - S_CONV
;
*value
= (pp
->safety
[safe
]!=S_UNKNOWN
? 3 : 4);
if (op
->safety
[safe
] == S_PLAYED
)
*value
*= Numneed
[oppos
] +
if (!pp
->mileage
|| foundend
||
if (op
->mileage
== 0 || onecard(op
))
if (op
->speed
== C_LIMIT
)
pp
->safety
[safe
] != S_UNKNOWN
)
if (op
->safety
[S_RIGHT_WAY
] == S_PLAYED
)
*value
= (pp
->safety
[S_RIGHT_WAY
] !=
*value
*= Numcards
[C_STOP
] +
if (!pp
->mileage
|| foundend
||
if (cango
&& pp
->safety
[S_RIGHT_WAY
] !=
case C_GAS_SAFE
: case C_DRIVE_SAFE
:
case C_SPARE_SAFE
: case C_RIGHT_WAY
:
*value
= cango
? 0 : 101;
*value
= cango
? 0 : 101;
mvprintw(i
+ 6, 2, "%3d %-14s", *value
,
if (!pp
->can_go
&& !isrepair(pp
->battle
))
Numneed
[opposite(pp
->battle
)]++;
mvaddstr(MOVE_Y
+ 1, MOVE_X
, "PLAY\n");
if (!Debug
|| Movetype
== M_DRAW
) {
if (Movetype
== M_DRAW
) {
if (issafety(pp
->hand
[nummin
])) { /* NEVER discard a safety */
mvaddstr(MOVE_Y
+ 1, MOVE_X
, "DISCARD\n");
if (!Debug
|| Movetype
== M_DRAW
) {
if (Movetype
== M_DRAW
) {
mvprintw(MOVE_Y
+ 2, MOVE_X
, "%16s", C_name
[pp
->hand
[Card_no
]]);
register CARD bat
, spd
, card
;
if (pp
->can_go
|| ((isrepair(bat
) || bat
== C_STOP
|| spd
== C_LIMIT
) &&
Numseen
[S_RIGHT_WAY
] != 0) ||
Numseen
[safety(bat
)] != 0)
switch (End
- pp
->mileage
) {
if (pp
->nummiles
[C_200
] == 2)
card
= (End
- pp
->mileage
== 75 ? C_75
: C_100
);
return Numseen
[S_RIGHT_WAY
] == 0;
card
= (End
- pp
->mileage
== 25 ? C_25
: C_50
);
return Numseen
[card
] != Numcards
[card
];
if (pp
->nummiles
[C_200
] == 2)
if (pp
->speed
== C_LIMIT
)
if (pp
->mileage
+ Value
[card
] > End
)
case C_EMPTY
: case C_FLAT
: case C_CRASH
:
if (op
->can_go
&& op
->safety
[safety(card
) - S_CONV
] != S_PLAYED
)
if (op
->speed
!= C_LIMIT
&&
op
->safety
[S_RIGHT_WAY
] != S_PLAYED
&&
case C_GAS
: case C_SPARE
: case C_REPAIRS
:
if (pp
->battle
== opposite(card
))
(isrepair(pp
->battle
) || pp
->battle
== C_STOP
))
if (pp
->speed
== C_LIMIT
)