Skip to content

Commit 1929f09

Browse files
committed
move tests to a CSV for easier portability
1 parent e0af1dc commit 1929f09

2 files changed

Lines changed: 116 additions & 79 deletions

File tree

data/test_binary_fen_cases.csv

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
binary_fen,canonical_binary_fen,fen,variant
2+
0000000000000000000003,0000000000000000000003,8/8/8/8/8/8/8/8 w - - 0 1,standard
3+
0000000000000000000103,0000000000000000000103,8/8/8/8/8/8/8/8 b - - 0 1,standard
4+
00000000000000800f000103,00000000000000800f000103,8/8/8/8/8/8/8/7k b - - 0 1,standard
5+
0000000000000000000203,0000000000000000000203,8/8/8/8/8/8/8/8 w - - 0 2,standard
6+
0000000000000000000303,0000000000000000000303,8/8/8/8/8/8/8/8 b - - 0 2,standard
7+
000000000000000064df0603,000000000000000064df0603,8/8/8/8/8/8/8/8 b - - 100 432,standard
8+
ffff00001000efff2d844ad200000000111111113e955fe3000103,ffff00001000efff2d844ad200000000111111113e955fe3000103,rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1,standard
9+
70c621102c00a3446a00004403111111730f013103,70c621102c00a3446a00004403111111730f013103,4nrk1/1pp3pp/p4p2/4P3/2BB1n2/8/PP3P1P/2K3R1 b - - 1 25,standard
10+
20400006400000080ac0b1000003,20400006400000080ac0b1000003,5k2/6p1/8/1Pp5/6P1/8/8/3K4 w - c6 0 1,standard
11+
10000000180040802ac10f000103,10000000180040802ac10f000103,4k3/8/8/8/3pP3/8/6N1/7K b - e3 0 1,standard
12+
917d731812a4ff91ad0d004400201801203531111119e5eb000003,917d731812a4ff91ad0d004400201801203531111119e5eb000003,r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1,standard
13+
95dd00000000dd95ad8d000000111111be9e000003,95dd00000000dd95ad8d000000111111be9e000003,r1k1r2q/p1ppp1pp/8/8/8/8/P1PPP1PP/R1K1R2Q w KQkq - 0 1,chess960
14+
a5dd00000000dda5ad8d000000111111be9e000003,a5dd00000000dda5ad8d000000111111be9e000003,r1k2r1q/p1ppp1pp/8/8/8/8/P1PPP1PP/R1K2R1Q w KQkq - 0 1,chess960
15+
00000090c0002094ad0b2354010003,00000090c0002094ad0b2354010003,8/8/8/4B2b/6nN/8/5P2/2R1K2k w Q - 1 1,chess960
16+
040000000000c019ab0d70000203,040000000000c019ab0d70000203,2r5/8/8/8/8/8/6PP/k2KR3 w K - 0 2,chess960
17+
100800000000c02bd9da007b020003,100800000000c02bd9da007b020003,4r3/3k4/8/8/8/8/6PP/qR1K1R2 w KQ - 2 1,chess960
18+
704f1ee8e81e4f70d60a44000002020813191113511571be000403,704f1ee8e81e4f70d60a44000002020813191113511571be000403,4rrk1/pbbp2p1/1ppnp3/3n1pqp/3N1PQP/1PPNP3/PBBP2P1/4RRK1 w Ff - 0 3,chess960
19+
00000002180000308a1c0f030103,00000002180000308a1c0f030103,8/8/8/1k6/3Pp3/8/8/4KQ2 b - d3 3 1,standard
20+
8901080000810091ad0d10e1f7000703,8901080000810091ad0d10e1f7000703,r2r3k/p7/3p4/8/8/P6P/8/R3K2R b KQq - 0 4,chess960
21+
53b7486001243edc24da060000425013111111e1b30e041403,53b7486001243edc24da060000425013111111e1b30e041403,rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR w Gkq - 4 11,chess960
22+
0000000000000c026a0b000003,0000000000000c026a0b000003,8/8/8/8/8/8/2Rk4/1K6 w - - 0 1,standard
23+
bb5844275dedffff00000000000000000000000000c0001050133eb9e5001608,bb5844275dedffff00000000000000000000000000c0001050133eb9e5001608,rn1qkb1r/3bn1p1/2p3P1/pPP2P2/P1PPP1P1/P1PP1PPP/PPPPPPPP/PPPPPPPP w kq a6 0 12,horde
24+
009494000101d7a1460600002081421101001906,009494000101d7a1460600002081421101001906,8/2p1p2p/2Q1N2B/8/p7/N7/PPP1P1PP/R4B1R b - - 0 13,antichess
25+
0081104243088000001c011011000106,0081104243088000001c011011000106,8/p6p/4p3/1P4P1/Pp4p1/3P4/7P/8 b - a3 0 1,antichess
26+
00811042c208010000110c1011000106,00811042c208010000110c1011000106,8/p6p/4p3/1P4P1/1p4pP/3P4/P7/8 b - h3 0 1,antichess
27+
008010434a0081000001c10011000206,008010434a0081000001c10011000206,8/7p/4p3/pP4P1/1p1P2p1/8/P6P/8 w - a6 0 2,antichess
28+
000110c24a008100000101c011000206,000110c24a008100000101c011000206,8/p7/4p3/1P4Pp/1p1P2p1/8/P6P/8 w - h6 0 2,antichess
29+
8fd720080000ffbf2d844a0d00000010111111715379000707,8fd720080000ffbf2d844a0d00000010111111715379000707,rnbq3r/ppp1p1pp/5p2/3p4/8/8/PPPPPPPP/RNBQKB1R b KQ - 0 4,atomic
30+
00c0a40810816892a70d000410111301002107,00c0a40810816892a70d000410111301002107,8/6pp/2p2p1n/3p4/4P3/B6P/3P1PP1/1r2K2R b K - 0 17,atomic
31+
000000000000ffff793542867b3542a6000009,000000000000ffff793542867b3542a6000009,8/8/8/8/8/8/krbnNBRK/qrbnNBRQ w - - 0 1,racing_kings
32+
0000000000407fff793542867f3542a6010109,0000000000407fff793542867f3542a6010109,8/8/8/8/8/6K1/krbnNBR1/qrbnNBRQ b - - 1 1,racing_kings
33+
efe708901800e7e7264462000000a0811f111171535973000d04,efe708901800e7e7264462000000a0811f111171535973000d04,rnbq1bnr/ppp2ppp/3k4/4p2Q/3PK3/8/PPP2PPP/RNB2BNR b - - 0 7,koth
34+
62d72832805ca341a600684004101591512111770f03290521,62d72832805ca341a600684004101591512111770f03290521,1r3rk1/pbp1N1pp/3p1q2/1p2bp2/7P/2PBB1P1/PP3Q1R/R5K1 b - - 1+2 3 21,three_check
35+
a28d72240048f761660a00000400511191b11187030236011021200100,a28d72240048f761660a00000400511191b11187030236011021200100,1r3Q1n/p1kp3p/1p2ppq1/2p2b2/8/3P2P1/PPP1PPBP/R4RK1[RNbbnnp] w - - 2 28,crazyhouse
36+
f9bd4b0100c1adee4248a200006060179011111151b3350801020100000001008000000000000000,f9bd4b0100c1adee4248a200006060179011111151b3350801020100000001008000000000000000,b2nkbnQ~/p1pppp1p/pP1q2p1/r7/8/R5PR/P1PP1P1P/1NBQ1BNK[R] w - - 1 2,crazyhouse
37+
00000000000000000000010000000000,00000000000000000000010000000000,8/8/8/8/8/8/8/8[] w - - 0 1,crazyhouse
38+
ffff00000000ffff2d844ad200000000111111113e955be30000010000000000ef0000000000002a,ffff00000000ffff2d844ad200000000111111113e955be30000010000000000ef0000000000002a,r~n~b~q~kb~n~r~/pppppppp/8/8/8/8/PPPPPPPP/RN~BQ~KB~NR[] w KQkq - 0 1,crazyhouse
39+
0000000000000000,0000000000000000,8/8/8/8/8/8/8/8 w - - 0 1,chess960
40+
00000000000000000001,00000000000000000001,8/8/8/8/8/8/8/8 b - - 0 1,chess960
41+
000000000000000064df06,000000000000000064df06,8/8/8/8/8/8/8/8 b - - 100 432,chess960
42+
ffff00001000efff2d844ad200000000111111113e955fe3,ffff00001000efff2d844ad200000000111111113e955fe3,rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1,chess960
43+
20400006400000080ac0b1,20400006400000080ac0b1,5k2/6p1/8/1Pp5/6P1/8/8/3K4 w - c6 0 1,chess960
44+
10000000180040802ac10f,10000000180040802ac10f,4k3/8/8/8/3pP3/8/6N1/7K b - e3 0 1,chess960
45+
8901080000810091ad0d10e1f70007,8901080000810091ad0d10e1f70007,r2r3k/p7/3p4/8/8/P6P/8/R3K2R b KQq - 0 4,chess960
46+
95dd00000000dd95ad8d000000111111be9e,95dd00000000dd95ad8d000000111111be9e,r1k1r2q/p1ppp1pp/8/8/8/8/P1PPP1PP/R1K1R2Q w KQkq - 0 1,chess960
47+
00000002180000308a1c0f030103,00000002180000308a1c0f030103,8/8/8/1k6/3Pp3/8/8/4KQ2 b - d3 3 1,chess960
48+
704f1ee8e81e4f70d60a44000002020813191113511571be000402,704f1ee8e81e4f70d60a44000002020813191113511571be000402,4rrk1/pbbp2p1/1ppnp3/3n1pqp/3N1PQP/1PPNP3/PBBP2P1/4RRK1 w Ff - 0 3,chess960
49+
ffff00000000ffff2d844ad200000000111111113e955be3000004,ffff00000000ffff2d844ad200000000111111113e955be3000004,rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1,koth
50+
ffff00000000ffff2d844ad200000000111111113e955be363000501,ffff00000000ffff2d844ad200000000111111113e955be363000501,rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 99 1 +0+1,three_check
51+
00800000000008001a000106,00800000000008001a000106,8/7p/8/8/8/8/3K4/8 b - - 0 1,antichess
52+
ffff00000000ffff2d844ad200000000111111113e955be3020407,ffff00000000ffff2d844ad200000000111111113e955be3020407,rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 2 3,atomic
53+
ffff0066ffffffff000000000000000000000000000000000000111111113e955be3000008,ffff0066ffffffff000000000000000000000000000000000000111111113e955be3000008,rnbqkbnr/pppppppp/8/1PP2PP1/PPPPPPPP/PPPPPPPP/PPPPPPPP/PPPPPPPP w kq - 0 1,horde
54+
000000000000ffff793542867b3542a6000009,000000000000ffff793542867b3542a6000009,8/8/8/8/8/8/krbnNBRK/qrbnNBRQ w - - 0 1,racing_kings
55+
ffff00000000ffff2d844ad200000000111111113e955be300e407010000000000ef0000000000002a,ffff00000000ffff2d844ad200000000111111113e955be300e407010000000000ef0000000000002a,r~n~b~q~kb~n~r~/pppppppp/8/8/8/8/PPPPPPPP/RN~BQ~KB~NR/ w KQkq - 0 499,crazyhouse
56+
ffff00000000ffff2d844ad200000000111111113e955be30000010000000000,ffff00000000ffff2d844ad200000000111111113e955be30000010000000000,rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR/ w KQkq - 0 1,crazyhouse

test_binary_fen.py

Lines changed: 60 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import asyncio
66
import copy
7+
import csv
78
import logging
89
import os
910
import os.path
@@ -23,16 +24,8 @@
2324
from chess import Board
2425
from chess.binary_fen import BinaryFen, ChessHeader, VariantHeader
2526

26-
KOTH = chess.variant.KingOfTheHillBoard
27-
THREE_CHECKS = chess.variant.ThreeCheckBoard
28-
ANTI = chess.variant.AntichessBoard
29-
ATOMIC = chess.variant.AtomicBoard
30-
HORDE = chess.variant.HordeBoard
31-
RK = chess.variant.RacingKingsBoard
32-
ZH = chess.variant.CrazyhouseBoard
3327

3428
class BinaryFenTestCase(unittest.TestCase):
35-
3629
def test_nibble_roundtrip(self):
3730
for lo in range(16):
3831
for hi in range(16):
@@ -170,78 +163,66 @@ def test_to_canonical_2(self):
170163
canon_case = case.to_canonical()
171164
self.assertEqual(canon, canon_case)
172165

173-
def test_binary_fen_roundtrip(self):
174-
cases = [
175-
Board(fen="8/8/8/8/8/8/8/8 w - - 0 1"),
176-
Board(fen="8/8/8/8/8/8/8/8 b - - 0 1"),
177-
Board(fen="8/8/8/8/8/8/8/7k b - - 0 1"),
178-
Board(fen="8/8/8/8/8/8/8/8 w - - 0 2"),
179-
Board(fen="8/8/8/8/8/8/8/8 b - - 0 2"),
180-
Board(fen="8/8/8/8/8/8/8/8 b - - 100 432"),
181-
Board(fen="rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1"),
182-
Board(fen="4nrk1/1pp3pp/p4p2/4P3/2BB1n2/8/PP3P1P/2K3R1 b - - 1 25"),
183-
Board(fen="4nrk1/1pp3pp/p4p2/4P3/2BB1n2/8/PP3P1P/2K3R1 b - - 1 25"),
184-
Board(fen="5k2/6p1/8/1Pp5/6P1/8/8/3K4 w - c6 0 1"),
185-
Board(fen="4k3/8/8/8/3pP3/8/6N1/7K b - e3 0 1"),
186-
Board(fen="r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1"),
187-
Board(fen="r1k1r2q/p1ppp1pp/8/8/8/8/P1PPP1PP/R1K1R2Q w KQkq - 0 1",chess960=True),
188-
Board(fen="r1k2r1q/p1ppp1pp/8/8/8/8/P1PPP1PP/R1K2R1Q w KQkq - 0 1", chess960=True),
189-
Board(fen="8/8/8/4B2b/6nN/8/5P2/2R1K2k w Q - 1 1", chess960=True),
190-
Board(fen="2r5/8/8/8/8/8/6PP/k2KR3 w K - 0 2", chess960=True),
191-
Board(fen="4r3/3k4/8/8/8/8/6PP/qR1K1R2 w KQ - 2 1", chess960=True),
192-
Board(fen="4rrk1/pbbp2p1/1ppnp3/3n1pqp/3N1PQP/1PPNP3/PBBP2P1/4RRK1 w Ff - 0 3", chess960=True),
193-
Board(fen="8/8/8/1k6/3Pp3/8/8/4KQ2 b - d3 3 1"),
194-
Board(fen="r2r3k/p7/3p4/8/8/P6P/8/R3K2R b KQq - 0 4",chess960=True),
195-
Board(fen="rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR w Gkq - 4 11", chess960=True),
196-
Board(fen="8/8/8/8/8/8/2Rk4/1K6 w - - 0 1"),
197-
198-
HORDE(fen="rn1qkb1r/3bn1p1/2p3P1/pPP2P2/P1PPP1P1/P1PP1PPP/PPPPPPPP/PPPPPPPP w kq a6 0 12"),
199-
200-
ANTI("8/2p1p2p/2Q1N2B/8/p7/N7/PPP1P1PP/R4B1R b - - 0 13"),
201-
ANTI("8/p6p/4p3/1P4P1/Pp4p1/3P4/7P/8 b - a3 0 1"),
202-
ANTI("8/p6p/4p3/1P4P1/1p4pP/3P4/P7/8 b - h3 0 1"),
203-
ANTI("8/7p/4p3/pP4P1/1p1P2p1/8/P6P/8 w - a6 0 2"),
204-
ANTI("8/p7/4p3/1P4Pp/1p1P2p1/8/P6P/8 w - h6 0 2"),
205-
206-
ATOMIC(fen="rnbq3r/ppp1p1pp/5p2/3p4/8/8/PPPPPPPP/RNBQKB1R b KQ - 0 4"),
207-
ATOMIC(fen="8/6pp/2p2p1n/3p4/4P3/B6P/3P1PP1/1r2K2R b K - 0 17"),
208-
209-
RK(fen="8/8/8/8/8/8/krbnNBRK/qrbnNBRQ w - - 0 1"),
210-
RK(fen="8/8/8/8/8/6K1/krbnNBR1/qrbnNBRQ b - - 1 1"),
211-
212-
KOTH(fen="rnbq1bnr/ppp2ppp/3k4/4p2Q/3PK3/8/PPP2PPP/RNB2BNR b - - 0 7"),
213-
214-
THREE_CHECKS(fen="1r3rk1/pbp1N1pp/3p1q2/1p2bp2/7P/2PBB1P1/PP3Q1R/R5K1 b - - 3 21 +2+1"),
215-
216-
ZH(fen="1r3Q1n/p1kp3p/1p2ppq1/2p2b2/8/3P2P1/PPP1PPBP/R4RK1/NRpnnbb w - - 2 28"),
217-
ZH(fen="b2nkbnQ~/p1pppp1p/pP1q2p1/r7/8/R5PR/P1PP1P1P/1NBQ1BNK/R w - - 1 2"),
218-
ZH(fen="8/8/8/8/8/8/8/8/ w - - 0 1"),
219-
ZH(fen="r~n~b~q~kb~n~r~/pppppppp/8/8/8/8/PPPPPPPP/RN~BQ~KB~NR/ w KQkq - 0 1"),
220-
]
221-
for case in cases:
222-
case_fen = case.fen()
223-
with self.subTest(fen=case_fen):
224-
bin_fen = BinaryFen.parse_from_board(case)
225-
bin_fen2 = BinaryFen.parse_from_bytes(bin_fen.to_bytes())
226-
self.assertEqual(bin_fen2, bin_fen2.to_canonical(), "from_bytes should produce canonical value")
227-
self.assertEqual(bin_fen.to_canonical(), bin_fen2.to_canonical())
228-
decoded, _ = bin_fen2.to_board()
229-
self.assertEqual(case, decoded)
230-
231-
232-
# tests that failed the fuzzer at some point
233-
def test_fuzzer_fail(self):
166+
_VARIANT_CLASSES = {
167+
"standard": lambda fen: chess.Board(fen=fen, chess960=False),
168+
"chess960": lambda fen: chess.Board(fen=fen, chess960=True),
169+
"koth": lambda fen: chess.variant.KingOfTheHillBoard(fen=fen),
170+
"three_check": lambda fen: chess.variant.ThreeCheckBoard(fen=fen),
171+
"antichess": lambda fen: chess.variant.AntichessBoard(fen=fen),
172+
"atomic": lambda fen: chess.variant.AtomicBoard(fen=fen),
173+
"horde": lambda fen: chess.variant.HordeBoard(fen=fen),
174+
"racing_kings": lambda fen: chess.variant.RacingKingsBoard(fen=fen),
175+
"crazyhouse": lambda fen: chess.variant.CrazyhouseBoard(fen=fen),
176+
}
177+
178+
def _run_case(self, binary_fen_hex, canonical_hex, fen, variant_name):
179+
expected_board = self._VARIANT_CLASSES[variant_name](fen)
180+
181+
decoded_board, std_mode = BinaryFen.decode(bytes.fromhex(binary_fen_hex))
182+
183+
encoded_hex = BinaryFen.encode(expected_board, std_mode=std_mode).hex()
184+
self.assertEqual(
185+
encoded_hex, canonical_hex, "encode(board) must equal canonical_binary_fen"
186+
)
187+
188+
self.assertEqual(
189+
decoded_board,
190+
expected_board,
191+
"decode(canonical_binary_fen) must equal board from FEN",
192+
)
193+
194+
parsed = BinaryFen.parse_from_bytes(bytes.fromhex(binary_fen_hex))
195+
self.assertEqual(
196+
parsed.to_canonical().to_bytes().hex(),
197+
canonical_hex,
198+
"parse_from_bytes(binary_fen).to_canonical() must equal canonical_binary_fen",
199+
)
200+
201+
def test_data_driven(self):
202+
csv_path = os.path.join(os.path.dirname(__file__), "data/test_binary_fen_cases.csv")
203+
with open(csv_path, newline="") as f:
204+
reader = csv.DictReader(f)
205+
for row in reader:
206+
with self.subTest(
207+
binary_fen=row["binary_fen"], fen=row["fen"], variant=row["variant"]
208+
):
209+
self._run_case(
210+
binary_fen_hex=row["binary_fen"],
211+
canonical_hex=row["canonical_binary_fen"],
212+
fen=row["fen"],
213+
variant_name=row["variant"] or "standard",
214+
)
234215
fuzz_fails = [
235-
"23d7",
236-
"e17f11efd84522d34878ffffffa600000000ce1b23ffff000943",
237-
"20f7076f1718f99824a5020724b3cfc1020146ae00004f85ae28aebc",
238-
"edf9b3c5cb7fa5008000004081c83e4092a7e63dd95a",
239-
"f7cef6e64ed47a4ede172a100000009b004c909b",
240-
"bb7cb00cc3f31dc3f325b8",
241-
"4584aced8100da50a20bd7251705a15b108000251705",
242-
"77ff05111f77111f4214e803647fff6429f0a2f65933310185016400000045bf1e8be6b013ed02",
243-
"55d648e9a20fd600400000e9a29c0010043b26fb41d50a50",
244-
"d8805347e76003102228687fffff41b19e2bff00000100020220c6"
216+
"23d7",
217+
"e17f11efd84522d34878ffffffa600000000ce1b23ffff000943",
218+
"20f7076f1718f99824a5020724b3cfc1020146ae00004f85ae28aebc",
219+
"edf9b3c5cb7fa5008000004081c83e4092a7e63dd95a",
220+
"f7cef6e64ed47a4ede172a100000009b004c909b",
221+
"bb7cb00cc3f31dc3f325b8",
222+
"4584aced8100da50a20bd7251705a15b108000251705",
223+
"77ff05111f77111f4214e803647fff6429f0a2f65933310185016400000045bf1e8be6b013ed02",
224+
"55d648e9a20fd600400000e9a29c0010043b26fb41d50a50",
225+
"d8805347e76003102228687fffff41b19e2bff00000100020220c6",
245226
]
246227
for fuzz_fail in fuzz_fails:
247228
with self.subTest(fuzz_fail=fuzz_fail):

0 commit comments

Comments
 (0)