Fix discovered check corner cases
authorFabian Fichter <ianfab@users.noreply.github.com>
Wed, 8 Jun 2022 20:46:11 +0000 (22:46 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Wed, 8 Jun 2022 20:48:57 +0000 (22:48 +0200)
src/position.cpp
test.py

index eaa37d6..2082461 100644 (file)
@@ -799,6 +799,7 @@ Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners
       slidingSnipers = snipers;
   }
   else
+  {
       for (PieceType pt : piece_types())
       {
           Bitboard b = sliders & (PseudoAttacks[~c][pt][s] ^ LeaperAttacks[~c][pt][s]) & pieces(c, pt);
@@ -821,6 +822,21 @@ Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners
                   slidingSnipers |= snipers & pieces(pt);
           }
       }
+      // Diagonal rook pins in Janggi palace
+      if (diagonal_lines() & s)
+      {
+          Bitboard diags = diagonal_lines() & PseudoAttacks[~c][BISHOP][s] & sliders & pieces(c, ROOK);
+          while (diags)
+          {
+              Square s2 = pop_lsb(diags);
+              if (!(attacks_from(c, ROOK, s2) & s))
+              {
+                  snipers |= s2;
+                  slidingSnipers |= s2;
+              }
+          }
+      }
+  }
   Bitboard occupancy = pieces() ^ slidingSnipers;
 
   while (snipers)
@@ -1340,6 +1356,12 @@ bool Position::gives_check(Move m) const {
       Square kto = make_square(rfrom > kfrom ? castling_kingside_file() : castling_queenside_file(), castling_rank(sideToMove));
       Square rto = kto + (rfrom > kfrom ? WEST : EAST);
 
+      // Is there a discovered check?
+      if (   castling_rank(WHITE) > RANK_1
+          && ((blockers_for_king(~sideToMove) & rfrom) || (non_sliding_riders() & pieces(sideToMove)))
+          && attackers_to(square<KING>(~sideToMove), (pieces() ^ kfrom ^ rfrom) | rto | kto, sideToMove))
+          return true;
+
       return   (PseudoAttacks[sideToMove][type_of(piece_on(rfrom))][rto] & square<KING>(~sideToMove))
             && (attacks_bb(sideToMove, type_of(piece_on(rfrom)), rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square<KING>(~sideToMove));
   }
diff --git a/test.py b/test.py
index 6b9cb91..ade9e97 100644 (file)
--- a/test.py
+++ b/test.py
@@ -728,6 +728,14 @@ class TestPyffish(unittest.TestCase):
         result = sf.gives_check("atomic", "8/8/kK6/8/8/8/Q7/8 b - - 0 1", [])
         self.assertFalse(result)
 
+        # Shako castling discovered check
+        result = sf.gives_check("shako", "10/5r4/2p3pBk1/1p6Pr/p3p5/9e/1PP2P4/P2P2PP2/ER3K2R1/8C1 w K - 7 38", ["f2h2"])
+        self.assertTrue(result)
+
+        # Janggi palace discovered check
+        result = sf.gives_check("janggi", "4ka3/4a4/9/4R4/2B6/9/9/5K3/4p4/3r5 b - - 0 113", ["e2f2"])
+        self.assertTrue(result)
+
     def test_game_result(self):
         result = sf.game_result("chess", CHESS, ["f2f3", "e7e5", "g2g4", "d8h4"])
         self.assertEqual(result, -sf.VALUE_MATE)