Add some additional sanity checks for move gen
All checks were successful
Python tests (make) / test (push) Successful in 12s

This commit is contained in:
2025-08-19 15:48:40 -04:00
parent 1ba87368b5
commit f0a2087bdd

View File

@@ -1,9 +1,11 @@
from test.base import ChessLibTestBase from test.base import ChessLibTestBase
from test.chess_ffi import Move from test.chess_ffi import Move
from test.chess_ffi import Board from test.chess_ffi import Board
from test.chess_ffi import sq_to_coord from test.chess_ffi import BLACK
from test.chess_ffi import WHITE
from test.chess_ffi import is_in_check
from test.chess_ffi import gen_legal_moves from test.chess_ffi import gen_legal_moves
from test.chess_ffi import sq
MAX_MOVES = 256 MAX_MOVES = 256
@@ -60,9 +62,45 @@ class TestLegalMoveGen(ChessLibTestBase):
self.assertEqual(n, 44) self.assertEqual(n, 44)
def test_pert_position_6(self): def test_perft_position_6(self):
fen = "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" fen = "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10"
b = Board(); self.load_fen(fen, board=b) b = Board(); self.load_fen(fen, board=b)
n, moves = self._gen_legal(b) n, moves = self._gen_legal(b)
self.assertEqual(n, 46) self.assertEqual(n, 46)
def test_stalemate_black_to_move(self):
# Classic stalemate: Black to move, no legal moves, not in check
fen = "7k/5Q2/6K1/8/8/8/8/8 b - - 0 1"
b = Board()
self.load_fen(fen, board=b)
moves = (Move * MAX_MOVES)()
n = gen_legal_moves(b, moves)
self.assertEqual(n, 0, "Stalemate should have 0 legal moves")
self.assertFalse(is_in_check(b, BLACK), "Side to move must not be in check in stalemate")
def test_simple_checkmate(self):
# Black to move; mated (Qg7# with Kg6 support)
fen = "7k/6Q1/6K1/8/8/8/8/8 b - - 0 1"
b = Board(); self.load_fen(fen, board=b)
moves = (Move * MAX_MOVES)()
n = gen_legal_moves(b, moves)
self.assertEqual(n, 0, "Checkmated side should have 0 legal moves")
self.assertTrue(is_in_check(b, BLACK), "Mated side must be in check")
def test_pinned_piece_cannot_move(self):
# White knight e2 pinned by rook e8 vs king e1
fen = "4r3/8/8/8/8/8/4N3/4K3 w - - 0 1"
b = Board(); self.load_fen(fen, board=b)
moves = (Move * MAX_MOVES)()
n = gen_legal_moves(b, moves)
for move in moves:
# Pinned knight cannot move from it's square.
self.assertFalse(getattr(move, "from") == sq("e2"))