#define PATH level==0 || path[0] == 0xc4028 && (level==1 /*|| path[1] == 0x75967 && (level == 2 || path[2] == 0x3400b && (level == 3))*/)\r
//define PATH 0\r
\r
+#define HASH\r
+\r
#include <stdio.h>\r
#include <stdlib.h>\r
#include <string.h>\r
#include <signal.h>\r
#include <time.h>\r
+#include <stdint.h>\r
\r
#ifdef WIN32 \r
# include <windows.h>\r
void pbytes(unsigned char *b);\r
\r
typedef struct {\r
+ int lock[5];\r
+ int move[5];\r
+ short int score[5];\r
+ char depth[5];\r
+ char flag[5];\r
+ char age[4];\r
+} HashBucket;\r
+\r
+HashBucket *hashTable;\r
+int hashMask;\r
+\r
+#define H_UPPER 2\r
+#define H_LOWER 1\r
+\r
+typedef struct {\r
char *name, *promoted;\r
int value;\r
signed char range[8];\r
int score, bestScore, curEval, iterAlpha;\r
Move move, nullMove;\r
UndoInfo tb;\r
+#ifdef HASH\r
+ Move hashMove; int index, nr, hit;\r
+#endif\r
if(PATH) /*pboard(board),pmap(attacks, BLACK),*/printf("search(%d) {%d,%d} eval=%d, stm=%d\n",depth,alpha,beta,difEval,stm),fflush(stdout);\r
xstm = stm ^ WHITE;\r
//printf("map made\n");fflush(stdout);\r
nodes++;\r
pv[pvPtr++] = 0; // start empty PV, directly behind PV of parent\r
\r
+\r
firstMove = curMove = sorted = msp += 50; // leave 50 empty slots in front of move list\r
- tb.fireMask = phase = 0; iterDep=1; replyDep = (depth < 1 ? depth : 1) - 1;\r
- do {\r
+ iterDep = 0; tb.fireMask = phase = 0;\r
+\r
+#ifdef HASH\r
+ index = hashKeyL & hashMask; nr = hashKeyL >> 30; hit = -1;\r
+ if(hashTable[index].lock[nr] == hashKeyH) hit = nr; else\r
+ if(hashTable[index].lock[4] == hashKeyH) hit = 4;\r
+ if(hit >= 0) {\r
+ bestScore = hashTable[index].score[hit];\r
+ if((bestScore <= alpha || hashTable[index].flag[hit] & H_LOWER) &&\r
+ (bestScore >= beta || hashTable[index].flag[hit] & H_UPPER) ) {\r
+ iterDep = hashTable[index].depth[hit];\r
+ }\r
+ } else { // decide on replacement\r
+ if(depth >= hashTable[index].depth[nr]) hit = nr; else hit = 4;\r
+ }\r
+#endif\r
+\r
+ replyDep = (depth < 1 ? depth : iterDep < 1 ? 1 : iterDep);\r
+ while(++iterDep <= depth) {\r
if(flag && depth>= 0) printf("iter %d:%d\n", depth,iterDep),fflush(stdout);\r
iterAlpha = alpha; bestScore = -INF; bestMoveNr = 0; resDep = 60;\r
for(curMove = firstMove; ; curMove++) { // loop over moves\r
//if(PATH) printf("mask=%x\n",tb.fireMask),pbytes(fireBoard);\r
phase = 1;\r
case 1: // hash move\r
+#ifdef HASH\r
+ if(hashMove) {\r
+ moveStack[sorted = msp++] = hashMove;\r
+ goto extractMove;\r
+ }\r
+#endif\r
phase = 2;\r
case 2: // capture-gen init\r
nextVictim = xstm;\r
if(GetTickCount() - startTime > tlim1) break; // do not start iteration we can (most likely) not finish\r
}\r
replyDep = iterDep;\r
- } while(++iterDep <= depth); // next depth\r
+#ifdef HASH\r
+ // hash store\r
+ hashTable[index].lock[hit] = hashKeyH;\r
+ hashTable[index].depth[hit] = iterDep;\r
+ hashTable[index].flag[hit] = (bestScore < beta) * H_UPPER;\r
+ if(bestScore > alpha) {\r
+ hashTable[index].flag[hit] |= H_LOWER;\r
+ hashTable[index].move[hit] = bestMoveNr ? moveStack[bestMoveNr] : 0;\r
+ } else hashTable[index].move[hit] = 0;\r
+#endif\r
+ } // next depth\r
retMSP = msp;\r
retFirst = firstMove;\r
msp = oldMSP; // pop move list\r
void\r
SetMemorySize (int n)\r
{\r
+#ifdef HASH\r
+ static HashBucket *realHash;\r
+ static int oldSize;\r
+ int m = 1;\r
+ intptr_t l;\r
+ if(n != oldSize) {\r
+ if(oldSize) free(realHash);\r
+ while(m*sizeof(HashBucket) <= n*512) m <<= 1;\r
+ m *= 1024; hashMask = m - 1;\r
+ realHash = calloc(m + 1, sizeof(HashBucket));\r
+ l = (intptr_t) realHash; hashTable = (HashBucket*) (l & ~63); // align with cache line\r
+ }\r
+#endif\r
}\r
\r
char *\r