// This software is copyright (c) 1996-2005 by // John Tromp // Insulindeweg 908 // 1095 DX Amsterdam // Netherlands // E-mail: tromp@cwi.nl // // 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 #include #define BOOKPLY 0 // full-width search up to this depth #define REPORTPLY -1 uint64 millisecs() { struct rusage rusage; getrusage(RUSAGE_SELF,&rusage); return rusage.ru_utime.tv_sec * 1000 + rusage.ru_utime.tv_usec / 1000; } int history[2][SIZE1]; uint64 nodes, msecs; int min(int x, int y) { return xy ? 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

= 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] | ((uint64)1 << height[i]))) return WIN; inithistory(); msecs = millisecs(); score = ab(LOSS, WIN); msecs = 1L + millisecs() - msecs; // prevent division by 0 return score; } int main() { int c, result, work; uint64 poscnt; if (sizeof(uint64) != 8) { printf("sizeof(uint64) == %d; please redefine.\n", sizeof(uint64)); exit(0); } trans_init(); puts("Fhourstones 3.1 (C)"); printf("Boardsize = %dx%d\n",WIDTH,HEIGHT); printf("Using %d transposition table entries.\n", TRANSIZE); for (;;) { reset(); while ((c = getchar()) != -1) { if (c >= '1' && c <= '0'+WIDTH) makemove(c - '1'); else if (c == '\n') break; } if (c == -1) 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("%llu pos / %llu msec = %.1f Kpos/sec\n", nodes, msecs, (double)nodes/msecs); htstat(); } return 0; }