Support combining duck with pseudo-royalty
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 2 Apr 2023 15:14:33 +0000 (17:14 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 2 Apr 2023 15:58:26 +0000 (17:58 +0200)
src/position.cpp
test.py

index ed12362..b1f9082 100644 (file)
@@ -1099,7 +1099,11 @@ bool Position::legal(Move m) const {
   if (var->extinctionPseudoRoyal)
   {
       Square kto = to;
-      Bitboard occupied = (type_of(m) != DROP ? pieces() ^ from : pieces()) | kto;
+      Bitboard occupied = (type_of(m) != DROP ? pieces() ^ from : pieces());
+      if (var->duckGating)
+          occupied ^= st->wallSquares;
+      if (wall_gating() || is_gating(m))
+          occupied |= gating_square(m);
       if (type_of(m) == CASTLING)
       {
           // After castling, the rook and king final positions are the same in
@@ -1111,10 +1115,12 @@ bool Position::legal(Move m) const {
           if (st->pseudoRoyals & from)
               for (Square s = from; s != kto; s += step)
                   if (  !(blast_on_capture() && (attacks_bb<KING>(s) & st->pseudoRoyals & pieces(~sideToMove)))
-                      && attackers_to(s, pieces() ^ from, ~us))
+                      && attackers_to(s, occupied, ~us))
                       return false;
-          occupied = (pieces() ^ from ^ to) | kto | rto;
+          // Move the rook
+          occupied ^= to | rto;
       }
+      occupied |= kto;
       if (type_of(m) == EN_PASSANT)
           occupied &= ~square_bb(capture_square(kto));
       if (capture(m) && blast_on_capture())
diff --git a/test.py b/test.py
index 8d79501..50420a0 100644 (file)
--- a/test.py
+++ b/test.py
@@ -74,6 +74,9 @@ startFen = rbnkbr/pppppp/6/6/PPPPPP/RBNKBR w KQkq - 0 1
 [passchess:chess]
 pass = true
 
+[royalduck:duck]
+extinctionPseudoRoyal = true
+
 [makhouse:makruk]
 startFen = rnsmksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSKMSNR[] w - - 0 1
 pieceDrops = true
@@ -936,6 +939,12 @@ class TestPyffish(unittest.TestCase):
         result = sf.game_result("atomic", "KQ6/Rk6/2B5/8/8/8/8/8 b - - 0 1", [])
         self.assertEqual(result, sf.VALUE_DRAW)
 
+        # royalduck checkmate and stalemate
+        result = sf.game_result("royalduck", "r1bqkbnr/pp1*p1p1/n2p1pQp/1Bp5/8/2N1PN2/PPPP1PPP/R1B1K2R b KQkq - 1 6", [])
+        self.assertEqual(result, -sf.VALUE_MATE)
+        result = sf.game_result("royalduck", "rnbqk1nr/pppp1ppp/4p3/8/7P/5Pb1/PPPPP*P1/RNBQKBNR w KQkq - 1 4", [])
+        self.assertEqual(result, sf.VALUE_MATE)
+
     def test_is_immediate_game_end(self):
         result = sf.is_immediate_game_end("capablanca", CAPA, [])
         self.assertFalse(result[0])