- initial import
git-svn-id: http://moon:8086/svn/mips@1 a8ebac50-d88d-4704-bea3-6648445a41b3
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
// This software is copyright (c) 1996-2008 by
|
||||
// John Tromp
|
||||
// 600 Route 25A
|
||||
// East Setauket
|
||||
// NY 11733
|
||||
// E-mail: john.tromp@gmail.com
|
||||
//
|
||||
// This notice must not be removed.
|
||||
// This software must not be sold for profit.
|
||||
// You may redistribute if your distributees have the
|
||||
// same rights and restrictions.
|
||||
|
||||
#include "TransGame.c"
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#define BOOKPLY 0 // additional plies to be searched full-width
|
||||
#define REPORTPLY 2 // additional plies on which to report value
|
||||
|
||||
unsigned long millisecs()
|
||||
{
|
||||
struct timeval t;
|
||||
|
||||
gettimeofday(&t, NULL);
|
||||
|
||||
return t.tv_sec * 1000 + t.tv_usec / 1000;
|
||||
}
|
||||
|
||||
int history[2][SIZE1];
|
||||
unsigned long nodes, msecs;
|
||||
int bookply,reportply;
|
||||
|
||||
int min(int x, int y) { return x<y ? x : y; }
|
||||
int max(int x, int y) { return x>y ? x : y; }
|
||||
|
||||
void inithistory()
|
||||
{
|
||||
int side,i,h;
|
||||
for (side=0; side<2; side++)
|
||||
for (i=0; i<(WIDTH+1)/2; i++)
|
||||
for (h=0; h<H1/2; h++)
|
||||
history[side][H1*i+h] = history[side][H1*(WIDTH-1-i)+HEIGHT-1-h] =
|
||||
history[side][H1*i+HEIGHT-1-h] = history[side][H1*(WIDTH-1-i)+h] =
|
||||
4+min(3,i) + max(-1,min(3,h)-max(0,3-i)) + min(3,min(i,h)) + min(3,h);
|
||||
}
|
||||
|
||||
int ab(int alpha, int beta)
|
||||
{
|
||||
int besti,i,j,l,v,val,score,ttscore;
|
||||
int winontop,work;
|
||||
int nav,av[WIDTH];
|
||||
uint64 poscnt;
|
||||
bitboard newbrd,other;
|
||||
int side,otherside;
|
||||
unsigned int hashindx,hashlock;
|
||||
|
||||
nodes++;
|
||||
if (nplies == SIZE-1) // one move left
|
||||
return DRAW; // by assumption, player to move can't win
|
||||
otherside = (side = nplies & 1) ^ 1;
|
||||
other = color[otherside];
|
||||
for (i = nav = 0; i < WIDTH; i++) {
|
||||
newbrd = other | ((bitboard)1 << height[i]); // check opponent move
|
||||
if (!islegal(newbrd))
|
||||
continue;
|
||||
winontop = islegalhaswon(other | ((bitboard)2 << height[i]));
|
||||
if (haswon(newbrd)) { // immediate threat
|
||||
if (winontop) // can't stop double threat
|
||||
return LOSS;
|
||||
nav = 0; // forced move
|
||||
av[nav++] = i;
|
||||
while (++i < WIDTH)
|
||||
if (islegalhaswon(other | ((bitboard)1 << height[i])))
|
||||
return LOSS;
|
||||
break;
|
||||
}
|
||||
if (!winontop)
|
||||
av[nav++] = i;
|
||||
}
|
||||
if (nav == 0)
|
||||
return LOSS;
|
||||
if (nplies == SIZE-2) // two moves left
|
||||
return DRAW; // opponent has no win either
|
||||
if (nav == 1) {
|
||||
makemove(av[0]);
|
||||
score = LOSSWIN-ab(LOSSWIN-beta,LOSSWIN-alpha);
|
||||
backmove();
|
||||
return score;
|
||||
}
|
||||
ttscore = transpose();
|
||||
if (ttscore != UNKNOWN) {
|
||||
if (ttscore == DRAWLOSS) {
|
||||
if ((beta = DRAW) <= alpha)
|
||||
return ttscore;
|
||||
} else if (ttscore == DRAWWIN) {
|
||||
if ((alpha = DRAW) >= beta)
|
||||
return ttscore;
|
||||
} else return ttscore; // exact score
|
||||
}
|
||||
hashindx = htindex;
|
||||
hashlock = lock;
|
||||
poscnt = posed;
|
||||
besti=0;
|
||||
score = LOSS;
|
||||
for (i = 0; i < nav; i++) {
|
||||
val = history[side][(int)height[av[l = i]]];
|
||||
for (j = i+1; j < nav; j++) {
|
||||
v = history[side][(int)height[av[j]]];
|
||||
if (v > val) {
|
||||
val = v; l = j;
|
||||
}
|
||||
}
|
||||
for (j = av[l]; l>i; l--)
|
||||
av[l] = av[l-1];
|
||||
makemove(av[i] = j);
|
||||
val = LOSSWIN-ab(LOSSWIN-beta,LOSSWIN-alpha);
|
||||
backmove();
|
||||
if (val > score) {
|
||||
besti = i;
|
||||
if ((score=val) > alpha && nplies >= bookply && (alpha=val) >= beta) {
|
||||
if (score == DRAW && i < nav-1)
|
||||
score = DRAWWIN;
|
||||
if (besti > 0) {
|
||||
for (i = 0; i < besti; i++)
|
||||
history[side][(int)height[av[i]]]--; // punish bad histories
|
||||
history[side][(int)height[av[besti]]] += besti;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (score == LOSSWIN-ttscore) // combine < and >
|
||||
score = DRAW;
|
||||
poscnt = posed - poscnt;
|
||||
for (work=0; (poscnt>>=1) != 0; work++) ; // work=log #positions stored
|
||||
transtore(hashindx, hashlock, score, work);
|
||||
if (nplies <= reportply) {
|
||||
printMoves();
|
||||
printf("%c%d\n", "#-<=>+"[score], work);
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
int solve()
|
||||
{
|
||||
int i, side = nplies & 1, otherside = side ^ 1, score;
|
||||
|
||||
nodes = 0;
|
||||
msecs = 1L;
|
||||
if (haswon(color[otherside]))
|
||||
return LOSS;
|
||||
for (i = 0; i < WIDTH; i++)
|
||||
if (islegalhaswon(color[side] | ((bitboard)1 << height[i])))
|
||||
return WIN;
|
||||
inithistory();
|
||||
reportply = nplies + REPORTPLY;
|
||||
bookply = nplies + BOOKPLY;
|
||||
msecs = millisecs();
|
||||
score = ab(LOSS, WIN);
|
||||
msecs = 1L + millisecs() - msecs; // prevent division by 0
|
||||
return score;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int c, result, work;
|
||||
uint64 poscnt;
|
||||
char init_str[] = "45461667\n35333571\n13333111\n\n";
|
||||
char *pStr = init_str;
|
||||
if (SIZE1 > 8*sizeof(bitboard)) {
|
||||
printf("sizeof(bitboard)=%lu bits, but need %d. please redefine.\n", 8*sizeof(bitboard), SIZE1);
|
||||
exit(0);
|
||||
}
|
||||
if (TRANSIZE < ((bitboard)1 << (SIZE1-LOCKSIZE))*31/32) {
|
||||
printf("transposition table size %d significantly smaller than 2^{(WIDTH*(HEIGHT+1)-LOCKSIZE}=2^{%d-%d}\nplease redefine.\n", TRANSIZE,SIZE1,LOCKSIZE);
|
||||
exit(0);
|
||||
}
|
||||
trans_init();
|
||||
puts("Fhourstones 3.2 (C)");
|
||||
printf("Boardsize = %dx%d\n",WIDTH,HEIGHT);
|
||||
printf("Using %d transposition table entries of size %lu.\n", TRANSIZE, sizeof(hashentry));
|
||||
|
||||
for (;;) {
|
||||
reset();
|
||||
while ((c = *pStr++) != 0) {
|
||||
if (c >= '1' && c <= '0'+WIDTH)
|
||||
makemove(c - '1');
|
||||
else if (c == '\n')
|
||||
break;
|
||||
}
|
||||
if (c == 0)
|
||||
break;
|
||||
printf("\nSolving %d-ply position after ", nplies);
|
||||
printMoves();
|
||||
puts(" . . .");
|
||||
|
||||
emptyTT();
|
||||
result = solve(); // expect score << 6 | work
|
||||
poscnt = posed;
|
||||
for (work=0; (poscnt>>=1) != 0; work++) ; //work = log of #positions stored
|
||||
printf("score = %d (%c) work = %d\n",
|
||||
result, "#-<=>+"[result], work);
|
||||
printf("%lu pos / %lu msec = %.1f Kpos/sec\n",
|
||||
nodes, msecs, (double)nodes/msecs);
|
||||
htstat();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user