Make length of repeat key symbolic
authorH.G.Muller <hgm@hgm-xboard.(none)>
Tue, 10 Apr 2018 19:48:18 +0000 (21:48 +0200)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Thu, 12 Apr 2018 07:13:50 +0000 (09:13 +0200)
The number of bits of the boar key in the total repeat key is now #defined
by a macro REPLEN, instead of being a numeric constant. (The remaining bits
contain the evaluation score.) This way it can be easily changed. (Which
might be needed to prevent overflow of the evaluation part, at the expense
of more false repetition detects.)

dropper.c

index 8bfb7e4..6a4ad7e 100644 (file)
--- a/dropper.c
+++ b/dropper.c
@@ -34,6 +34,9 @@
 #define C_DISTANT 0xFF00
 #define C_CONTACT 0x00FF
 
+#define REPLEN 20
+#define REPKEY ~(-1 << REPLEN)
+
 typedef long long int Key;
 
 int ply, nodeCount, forceMove, choice, rootMove, lastGameMove, rootScore, abortFlag, postThinking=1; // some frequently used data
@@ -611,8 +614,8 @@ GameInit (char *name)
     for(i=0; *ip >= 0; i++) pieceValues[WHITE+i] = pieceValues[BLACK+i] = *ip++;       // basic
     for(i=16,ip++; *ip >= 0; i++) pieceValues[WHITE+i] = pieceValues[BLACK+i] = *ip++; // promoted
     for(i=0, ip++; *ip >= 0; i++) handVal[WHITE+i] = handVal[BLACK+i] = *ip++;         // in hand
-    pawn = 2*handVal[WHITE] << 20; // used for detection of material-loosing loop
-    queen = v ? 0 : 2*handVal[WHITE+4] << 20; // losing two Queens overflows
+    pawn = 2*handVal[WHITE] << REPLEN; // used for detection of material-loosing loop
+    queen = v ? 0 : 2*handVal[WHITE+4] << REPLEN; // losing two Queens overflows
     for(i=0; i<16; i++) {
        int demoted = dropType[handSlot[WHITE+i+16]]-1; // piece type after demotion (could be Pawn, in Chess)
        handVal[WHITE+i+16] = handVal[BLACK+i+16] = pieceValues[WHITE+i+16] + handVal[demoted];   // gain by capturing promoted piece
@@ -1408,10 +1411,10 @@ Search (int stm, int alpha, int beta, StackFrame *ff, int depth, int reduction,
 
                // repetition checking
                int index = (unsigned int)f.newKey >> 24 ^ stm << 2; // uses high byte of low (= hands-free) key
-               while(repKey[index] && (repKey[index] ^ (int)f.newKey) & 0xFFFFF) index++;
+               while(repKey[index] && (repKey[index] ^ (int)f.newKey) & REPKEY) index++;
                int oldRepKey = repKey[index], oldRepDep = repDep[index];
                if(oldRepKey && ff->mutation != -2) { // key present in table: (quasi-)repetition
-                   int gain = (f.newEval << 20) - (repKey[index] & 0xFFF00000);
+                   int gain = (f.newEval << REPLEN) - (repKey[index] & ~REPKEY);
                    if(gain == 0) { // true repeat
                        score = 0;
                        if(perpLoses) { // repetitions not always draw
@@ -1427,8 +1430,8 @@ Search (int stm, int alpha, int beta, StackFrame *ff, int depth, int reduction,
                           
                        }
                    }
-                   else if(gain == pawn  || gain == queen  || gain >= (400<<20)) score = INF-1;  // quasi-repeat with extra piece in hand
-                   else if(gain == -pawn || gain == -queen || gain <= (-400<<20)) score = 1-INF; // or with one piece less
+                   else if(gain == pawn  || gain == queen  || gain >= (400<<REPLEN)) score = INF-1;  // quasi-repeat with extra piece in hand
+                   else if(gain == -pawn || gain == -queen || gain <= (-400<<REPLEN)) score = 1-INF; // or with one piece less
                    else goto search;// traded one hand piece for another; could still lead somewhere
                    f.lim = score; f.depth = (score >= beta ? highDepth+1 : iterDepth); // minimum required depth
                    *pvPtr = 0; // fake that daughter returned empty PV
@@ -1438,7 +1441,7 @@ Search (int stm, int alpha, int beta, StackFrame *ff, int depth, int reduction,
                    lmr = (curMove >= m.late) + (curMove >= m.drops);
                    f.tpGain = f.newEval + ff->pstEval;     // material gain in last two ply
                    if(ply==0 && randomize && moveNr < 10) ran = (alpha > INF-100 || alpha <-INF+100 ? 0 : (f.newKey*ranKey>>24 & 31)- 16);
-                   repKey[index] = (int)f.newKey & 0xFFFFF | f.newEval << 20; repDep[index] = ply + moveNr; // remember position
+                   repKey[index] = (int)f.newKey & REPKEY | f.newEval << REPLEN; repDep[index] = ply + moveNr; // remember position
                    // recursion
                    deprec[ply] = (f.checker != CK_NONE ? f.checker : 0)<<24 | maxDepth<<16 | depth<< 8 | iterDepth; path[ply++] = moveStack[curMove] & 0xFFFF;
                    score = -Search(stm, -beta, -alpha+ran, &f, iterDepth-1, lmr, highDepth);
@@ -1771,7 +1774,7 @@ RootMakeMove(int move)
   // store in game history hash table
   index = (unsigned int)undoInfo.newKey >> 24 ^ stm << 2; // uses high byte of low (= hands-free) key
   while(repKey[index] && (repKey[index] ^ (int)undoInfo.newKey) & 0xFFFFF) index++; // find empty slot
-  repKey[index] = (int)undoInfo.newKey & 0xFFFFF | undoInfo.newEval << 20; // remember position
+  repKey[index] = (int)undoInfo.newKey & REPKEY | undoInfo.newEval << REPLEN; // remember position
   repDep[index] = moveNr;
   stm ^= COLOR; moveNr++;
   return 1;