from test.base import ChessLibTestBase from binding.python_c_ffi import Board from binding.python_c_ffi import BLACK from binding.python_c_ffi import WHITE from binding.python_c_ffi import sq from binding.python_c_ffi import popcount from binding.python_c_ffi import get_rank_mask class TestFenLoading(ChessLibTestBase): def test_startpos_fields_and_occupancies(self): b = Board() fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" rc = self.chess_ffi.load_fen(b, fen) self.assertEqual(rc, 0) self.assertEqual(b.side_to_move, WHITE) self.assertEqual(b.castling_rights, 0b1111) self.assertEqual(b.ep_square, -1) self.assertEqual(b.halfmove_clock, 0) self.assertEqual(b.fullmove_number, 1) white_expected = get_rank_mask(0) | get_rank_mask(1) black_expected = get_rank_mask(6) | get_rank_mask(7) self.assertEqual(int(b.occ[WHITE]), white_expected) self.assertEqual(int(b.occ[BLACK]), black_expected) self.assertEqual(int(b.occ[2]), white_expected | black_expected) self.assertEqual(popcount(int(b.occ[WHITE])), 16) self.assertEqual(popcount(int(b.occ[BLACK])), 16) def test_castling_flags_parsing(self): b = Board() fen = "r3k2r/8/8/8/8/8/8/R3K2R b KQkq - 5 42" self.chess_ffi.load_fen(b, fen) self.assertEqual(b.side_to_move, BLACK) self.assertEqual(b.castling_rights, 0b1111) self.assertEqual(b.halfmove_clock, 5) self.assertEqual(b.fullmove_number, 42) def test_en_passant_targets(self): # EP at e6, black to move b1 = Board() fen = "8/8/8/3pP3/8/8/8/8 b KQkq e6 0 1" rc = self.chess_ffi.load_fen(b1, fen) self.assertEqual(rc, 0) self.assertEqual(b1.side_to_move, BLACK) self.assertEqual(b1.ep_square, sq("e6")) # EP at d3, white to move — use a fresh Board b2 = Board() fen = "8/8/8/8/3Pp3/8/8/8 w KQkq d3 12 7" rc = self.chess_ffi.load_fen(b2, fen) self.assertEqual(rc, 0) self.assertEqual(b2.side_to_move, WHITE) self.assertEqual(b2.ep_square, sq("d3")) def test_malformed_piece_field(self): # rank sums wrong (9 on a rank), bad char, missing separators bad = [ "9/8/8/8/8/8/8/8 w - - 0 1", "8/8/8/8/8/8/8/7x w - - 0 1", "8/8/8/8/8/8/8/8w - - 0 1", ] for fen in bad: r = self.chess_ffi.load_fen(Board(), fen) self.assertEqual(r, -1) def test_malformed_side_castling_ep(self): bad = [ "8/8/8/8/8/8/8/8 x - - 0 1", # bad side "8/8/8/8/8/8/8/8 w KX - 0 1", # bad castling char "8/8/8/8/8/8/8/8 w - j9 0 1", # bad EP square "8/8/8/8/8/8/8/8 w - e4 0 1", # EP not rank 3/6 (your code allows any 1..8; consider tightening) ] for fen in bad: r = self.chess_ffi.load_fen(Board(), fen) self.assertEqual(r, -1)