Evaluate perpetual checks in Shogi variants
authorH.G.Muller <hgm@hgm-xboard.(none)>
Mon, 15 May 2017 12:48:26 +0000 (14:48 +0200)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Mon, 15 May 2017 12:48:26 +0000 (14:48 +0200)
Detection of a repeat will now check if it is a perpetual check in variants
whre such is forbidden, (i.e. all but Crazyhouse). The checking side is then
rules  to lose.

dropper.c

index f607d32..c80e510 100644 (file)
--- a/dropper.c
+++ b/dropper.c
@@ -1335,8 +1335,21 @@ if(PATH)printf("%d:%d:%d new iter moveStack[%d..%d]\n",ply,depth,iterDepth,m.fir
                if(oldRepKey && ff->mutation != -2) { // key present in table: (quasi-)repetition
                    int gain = (f.newEval << 21) - (repKey[index] & 0xFFE00000);
                    if(gain == 0) { // true repeat
-                       score = 0; // draw score *** HERE WE SHOULD TEST FOR PERPETUALS IN SHOGI ***
-                   } else if(gain == pawn || gain > (450<<21)) score = INF;  // quasi-repeat with extra piece in hand
+                       score = 0;
+                       if(perpLoses) { // repetitions not always draw
+                           int i, d = repDep[index];
+                           for(i=moveNr+ply-1; i>=d; i-=2) if(checkHist[i+1] == CK_NONE) break;
+                           if(i < d) score = -INF; // we deliver a perpetual, so lose
+                           else {
+                               for(i=moveNr+ply-2; i>=d; i-=2) {if(PATH)printf("      %2d. %d\n",i,checkHist[i+1]);if(checkHist[i+1] == CK_NONE) break;}
+                               if(i < d) score = INF-1; // we are suffering a perpetual, so lose
+                               else if(perpLoses == 1) score = (stm == WHITE ? -INF : INF-1); // mini-Shogi, sente loses
+                               else if(perpLoses == 5) score = -INF; // Tori Shogi, repeating loses
+                           }
+                          
+                       }
+                   }
+                   else if(gain == pawn || gain > (450<<21)) score = INF;  // quasi-repeat with extra piece in hand
                    else if(gain == -pawn || gain < (-450<<21)) score = -INF; // or with one piece less
                    else goto search;// traded one hand piece for another; could still lead somewhere
                } else { // not a repeat: search it