Fix perpetual check detection
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 17 Nov 2019 11:54:18 +0000 (12:54 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 17 Nov 2019 11:54:18 +0000 (12:54 +0100)
Consider also perpetual checks by side to move
in order to avoid wrong draw scores.

Closes #49.

src/position.cpp

index 251680c..c007d0e 100644 (file)
@@ -1784,23 +1784,28 @@ bool Position::is_optional_game_end(Value& result, int ply) const {
       {
           StateInfo* stp = st->previous->previous;
           int cnt = 0;
-          bool perpetual = true;
+          bool perpetualThem = st->checkersBB && stp->checkersBB;
+          bool perpetualUs = st->previous->checkersBB && stp->previous->checkersBB;
 
           for (int i = 4; i <= end; i += 2)
           {
               stp = stp->previous->previous;
-              perpetual &= bool(stp->checkersBB);
+              perpetualThem &= bool(stp->checkersBB);
 
               // Return a draw score if a position repeats once earlier but strictly
               // after the root, or repeats twice before or at the root.
               if (   stp->key == st->key
                   && ++cnt + 1 == (ply > i ? 2 : n_fold_rule()))
               {
-                  result = convert_mate_value(  var->perpetualCheckIllegal && perpetual ? VALUE_MATE
+                  result = convert_mate_value(  var->perpetualCheckIllegal && perpetualThem ? VALUE_MATE
+                                              : var->perpetualCheckIllegal && perpetualUs ? -VALUE_MATE
                                               : var->nFoldValueAbsolute && sideToMove == BLACK ? -var->nFoldValue
                                               : var->nFoldValue, ply);
                   return true;
               }
+
+              if (i + 1 <= end)
+                  perpetualUs &= bool(stp->previous->checkersBB);
           }
       }
   }