|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 10677 (0x29b5)
Types: TextFile
Names: »strategy.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Challenge/strategy.c«
#include "challenge.h"
int ncall;
#ifdef DEBUG
int debug=1;
static FILE *log = NULL;
#endif
#define N_COMPUTER 0
#define N_HUMAN 1
#define N_TABLE 2
#define OPPONENT(s) (1 - (s))
#define INFINITE 0xffff
#define UNDEF 9999
#define BIT_SUIT(x) ((x)>>13)
#define BIT_VALUE(x) ((x)&0x1fff)
typedef struct {
char to_move, ply;
int top;
int n_cards[2];
int cards[3][4];
} position;
int stack[500];
int score[256][4];
int trumps[2];
int jimmy;
int last_score = 0;
store_moves(c, suit, my_cards, table_cards, mp)
int c, suit, my_cards, table_cards, *mp;
{
int n = 0;
suit <<= 13;
while(c) {
if(c & my_cards) {
*(mp++) = c | suit;
n++;
do {
c >>= 1;
} while(c & (my_cards | table_cards));
}
c >>= 1;
}
return n;
}
gen_moves(pos, mp)
position *pos;
int *mp;
{
int my_side, my_trump, his_trump;
int nm, h, top_suit, top_card;
int *my_cards, *table_cards;
my_side = pos->to_move;
my_cards = pos->cards[my_side];
table_cards = pos->cards[N_TABLE];
top_suit = BIT_SUIT(pos->top);
top_card = BIT_VALUE(pos->top);
my_trump = trumps[my_side];
his_trump = trumps[OPPONENT(my_side)];
if(top_card) {
*mp = 0;
nm = 1 + store_moves(top_card >> 1, top_suit, my_cards[top_suit],
table_cards[top_suit], mp + 1);
mp += nm;
if(top_suit != my_trump) {
nm += store_moves(jimmy, my_trump, my_cards[my_trump],
table_cards[my_trump], mp);
}
}
else {
nm = store_moves(jimmy, DIAMONDS, my_cards[DIAMONDS],
table_cards[DIAMONDS], mp);
mp += nm;
h = store_moves(jimmy, CLUBS, my_cards[CLUBS], table_cards[CLUBS], mp);
mp += h;
nm += h;
h = store_moves(jimmy, his_trump, my_cards[his_trump],
table_cards[his_trump], mp);
mp += h;
nm += h;
h = store_moves(jimmy, my_trump, my_cards[my_trump],
table_cards[my_trump], mp);
nm += h;
}
return(nm);
}
#define gscore(x0,x1,y0,y1,a0,a1,b0,b1) 6*x0+5*y0+3*x1+3*y1-a0-b0-2*a1-2*b1
static_eval(pos)
position *pos;
{
int my_side, his_side, my_trump, his_trump;
int x, x0, x1, dx,
y, y0, y1, dy,
a, a0, a1, da,
b, b0, b1, db, f1;
int tx, tx0, tx1, tdx,
ty, ty0, ty1, tdy,
ta, ta0, ta1, tda,
tb, tb0, tb1, tdb, f2;
my_side = pos->to_move;
his_side = OPPONENT(my_side);
my_trump = trumps[my_side];
his_trump = trumps[his_side];
{
register int *c_m = pos->cards[my_side];
register int *c_h = pos->cards[his_side];
register int *p;
p = score[c_m[my_trump]];
x0 = *(p++);
x1 = *(p++);
x = *(p++);
dx = *p;
p = score[c_h[his_trump]];
tx0 = *(p++);
tx1 = *(p++);
tx = *(p++);
tdx = *p;
p = score[c_m[his_trump]];
y0 = *(p++);
y1 = *(p++);
y = *(p++);
dy = *p;
p = score[c_h[my_trump]];
ty0 = *(p++);
ty1 = *(p++);
ty = *(p++);
tdy = *p;
p = score[c_m[CLUBS]];
a0 = *(p++);
a1 = *(p++);
a = *(p++);
da = *p;
p = score[c_h[CLUBS]];
tb0 = *(p++);
tb1 = *(p++);
tb = *(p++);
tdb = *p;
p = score[c_m[DIAMONDS]];
b0 = *(p++);
b1 = *(p++);
b = *(p++);
db = *p;
p = score[c_h[DIAMONDS]];
ta0 = *(p++);
ta1 = *(p++);
ta = *(p++);
tda = *p;
}
if(x1 + y1 + a + b <= 1) {
return(INFINITE);
}
if(tx0 == pos->n_cards[his_side]) {
return(-INFINITE);
}
if((tx) == 0 && x0 >= x1 - 1) {
register int n;
n = da;
n += db;
n += dx;
if(n <= x0 + 1) {
return(INFINITE);
}
}
if(x == 0 && tx0 >= x1) {
register int n;
n = tda;
n += tdb;
if(tx1 == tx0) {
n++;
}
if(n <= tx0) {
return(-INFINITE);
}
}
f1 = gscore(x0, x1, y0, y1, a0, a1, b0, b1);
f2 = gscore(tx0, tx1, ty0, ty1, ta0, ta1, tb0, tb1);
return(3 + f1 - f2);
}
#undef gscore
update(pos, mv)
register position *pos;
register int mv;
{
register int his_side = pos->to_move;
pos->to_move = OPPONENT(his_side);
pos->top = mv;
pos->ply += 1;
if(mv == 0) {
register int s;
pos->n_cards[his_side] = max_card - pos->n_cards[OPPONENT(his_side)];
for(s = 3; s >= 0; s--) {
pos->cards[his_side][s] |= pos->cards[N_TABLE][s];
pos->cards[N_TABLE][s] = 0;
}
} else {
register int suit;
pos->n_cards[his_side] -= 1;
suit = BIT_SUIT(mv);
pos->cards[N_TABLE][suit] |= BIT_VALUE(mv);
pos->cards[his_side][suit] ^= BIT_VALUE(mv);
}
}
eval(pos, mv , mvlist, alfa, beta)
position pos;
int mv, *mvlist, alfa, beta;
{
int nmoves, e, emax, i;
int nbeta = beta;
++ncall;
update(&pos, mv);
if(mv==0) {
if(pos.n_cards[pos.to_move] == 1) {
return(-INFINITE);
}
emax = static_eval(&pos);
if(pos.ply > depth) {
return(-emax);
}
if(emax == INFINITE) {
return(-INFINITE);
} else if(emax == -INFINITE) {
return(INFINITE);
}
}
nmoves = gen_moves(&pos,mvlist);
if(nmoves > 1 && (pos.n_cards[pos.to_move] == 1)) {
return(-INFINITE);
}
emax = -INFINITE;
for(i=0; i<nmoves; i++) {
e = eval(pos, mvlist[i], mvlist + nmoves, -nbeta, -alfa);
if(e > emax) {
emax = e;
}
if(emax >= alfa) {
break;
}
if(emax > nbeta) {
nbeta = emax;
}
}
return(-emax);
}
strategy(player)
int player;
{
static init = FALSE;
position pos;
int nmoves, emax, e, i;
int bestmv = 0;
if(depth == 0) {
return(zero_strategy(player));
}
#ifdef TIMER
set_alarm();
#endif
if(!init) {
init = TRUE;
loc_init();
}
init_pos(&pos, player);
#ifdef DEBUG
if(debug) {
print_pos(&pos);
}
#endif
nmoves = gen_moves(&pos, stack);
if(nmoves == 1) {
bestmv = stack[0];
emax = UNDEF;
} else if(nmoves > 1 && pos.n_cards[pos.to_move] == 1) {
bestmv = stack[1];
emax = INFINITE;
} else {
ncall = 0;
emax = -INFINITE;
bestmv = stack[1];
for(i=0; i<nmoves; i++) {
e = eval(pos, stack[i], stack + nmoves, -emax, -INFINITE);
#ifdef DEBUG
if(debug) {
printmve(0,stack[i],e);
}
#endif
if(e > emax)
{
emax = e;
bestmv = stack[i];
}
}
#ifdef DEBUG
if(debug) {
fprintf(log, "chosen ( %d )===> ", ncall);
printmve(0, bestmv, emax);
fflush(log);
}
#endif
}
#ifdef TIMER
end_alarm();
#endif
move(COMMENT_LINE, 1);
clrtoeol();
if(player == COMPUTER) {
if(emax == INFINITE || (last_score == INFINITE && emax == UNDEF)) {
printw("i think i am going to win!");
emax = INFINITE;
}
}
refresh();
last_score = emax;
if(bestmv == 0) {
return(PICK_UP);
}
if(player == COMPUTER) {
return(comp_ind(bestmv, &computer[0]));
} else {
return(comp_ind(bestmv, &human[0]));
}
}
loc_init()
{
int mcs, s0, s1;
int i;
#ifdef DEBUG
if(debug && log==0) {
unlink(DEBUG);
log = fopen(DEBUG, "w");
}
#endif
for(i=0; i<256; i++) {
s0 = 0;
s1 = 0;
mcs = i;
while(mcs & 1) {
mcs >>= 1;
s0++;
}
while(mcs) {
s1 += mcs&1;
mcs >>= 1;
}
score[i][0] = s0;
score[i][1] = s1;
score[i][2] = s0 + s1;
if(s1 > s0) {
score[i][3] = s1 - s0;
} else {
score[i][3] = 0;
}
}
}
#define SUIT1(x) ((x)&3)
#define VALUE1(x) (((x)>>2) & 15)
bit_to_int(mv)
int mv;
{
int s, c, v;
if(mv == 0) {
return(0);
}
s = BIT_SUIT(mv);
c = BIT_VALUE(mv);
for(v = 0; c > 1; c >>= 1) {
v++;
}
return(s + (v << 2));
}
comp_ind(c, deck)
char *deck;
{
int i;
c = bit_to_int(c);
for(i = 0; deck[i] != c ; i++);
return(i);
}
init_pos(pos, player)
position *pos;
int player;
{
int i, c;
trumps[N_COMPUTER] = SPADES;
trumps[N_HUMAN] = HEARTS;
jimmy = 1 << ((max_card >> 2) - 1);
if(nr_table == 0) {
pos->top = 0;
} else {
pos->top = (1 << VALUE1(top)) | (SUIT1(top) << 13);
}
if(player == COMPUTER) {
pos->to_move = N_COMPUTER;
} else {
pos->to_move = N_HUMAN;
}
pos->n_cards[N_COMPUTER] = nr_computer;
pos->n_cards[N_HUMAN] = nr_human;
pos->ply = 0;
for(i=0; i<4 ; i++) {
pos->cards[N_COMPUTER][i] = 0;
pos->cards[N_HUMAN][i] = 0;
pos->cards[N_TABLE][i] = 0;
}
for(i=0; i<nr_computer; i++) {
c = computer[i];
pos->cards[N_COMPUTER][SUIT1(c)] |= 1 << VALUE1(c);
}
for(i=0; i<nr_table; i++) {
c = table[i];
pos->cards[N_TABLE][SUIT1(c)] |= 1 << VALUE1(c);
}
for(i=0; i<nr_human; i++) {
c = human[i];
pos->cards[N_HUMAN][SUIT1(c)] |= 1 << VALUE1(c);
}
}
#ifdef DEBUG
printmv(mv)
int mv;
{
int c, sc, vc;
if(mv == 0) {
fprintf(log, " pu ");
} else {
c = bit_to_int(mv);
fprintf(log, " %c%c ", "AKQJX98765432"[VALUE(c)], "scdh"[SUIT(c)]);
}
}
printmve(level, mv, e)
int level, mv, e;
{
fprintf(log, "level:%d ", level);
printmv(mv);
fprintf(log, " = %d \n", e);
}
print_pos(pos)
position *pos;
{
int s, c, bl;
int *cp;
fprintf(log, "\n******************\n");
fprintf(log, "computer : \n");
cp = pos->cards[N_COMPUTER];
for(s = 0; s < 4; s++) {
bl = 0;
for(c = 1; c <= jimmy; c = c << 1) {
if(c & cp[s]) {
bl = 1;
printmv(c + (s << 13));
}
}
if(bl) {
fprintf(log, " \n");
}
}
fprintf(log, "human : \n");
cp = pos->cards[N_HUMAN];
for(s = 0; s < 4; s++) {
bl = 0;
for(c = 1; c <= jimmy; c = c << 1) {
if(c & cp[s]) {
bl = 1;
printmv(c + (s << 13));
}
}
if(bl) {
fprintf(log, " \n");
}
}
fprintf(log, "table : \n");
cp = pos->cards[N_TABLE];
for(s = 0; s < 4; s++) {
bl = 0;
for(c = 1; c <= jimmy; c = c << 1) {
if(c & cp[s]) {
bl = 1;
printmv(c + (s << 13));
}
}
if(bl) {
fprintf(log, " \n");
}
}
if(pos->top) {
fprintf(log, "on top >>>>");
printmv(pos->top);
fprintf(log, " <<<<\n");
}
}
#endif
zero_strategy(player)
int player;
{
int i, j = PICK_UP, iresult, jresult, nr_deck;
char *deck;
last_score = 0;
if(player == COMPUTER) {
deck = &computer[0];
nr_deck = nr_computer;
} else {
deck = &human[0];
nr_deck = nr_human;
}
jresult = evaluate_card(player, PICK_UP);
for(i = 0; i < nr_deck; i++) {
if(valid(player, i)) {
iresult = evaluate_card(player, deck[i]);
if(iresult > jresult) {
j = i;
jresult = iresult;
}
}
}
return(j);
}
evaluate_card(player, card)
int player, card;
{
int value, suit;
if(card == PICK_UP) {
return(-1);
}
value = VALUE(card);
suit = SUIT(card);
if(((player == COMPUTER) && (suit == SPADES)) ||
((player == HUMAN) && (suit == HEARTS))) {
return(value);
}
if(((player == COMPUTER) && (suit == HEARTS)) ||
((player == HUMAN) && (suit == SPADES))) {
return(value + size);
}
return(value + size2);
}
accept_draw()
{
return(last_score < -20);
}