[perft] A script that checks a list of positions against known node counts

A small Python script that reads a JSON list of positions and their known Perft
node counts to a certain depth, then invokes the Perft program for each position
and validates the output.

Peter Ellis Jones shared such a JSON list on GitHub. Import that file.
This commit is contained in:
Eryn Wells 2025-06-11 08:16:37 -07:00
parent 9815a63ebb
commit 3c31f900ea
2 changed files with 197 additions and 0 deletions

View file

@ -0,0 +1,117 @@
[
{
"depth":1,
"nodes":8,
"fen":"r6r/1b2k1bq/8/8/7B/8/8/R3K2R b KQ - 3 2"
},
{
"depth":1,
"nodes":8,
"fen":"8/8/8/2k5/2pP4/8/B7/4K3 b - d3 0 3"
},
{
"depth":1,
"nodes":19,
"fen":"r1bqkbnr/pppppppp/n7/8/8/P7/1PPPPPPP/RNBQKBNR w KQkq - 2 2"
},
{
"depth":1,
"nodes":5,
"fen":"r3k2r/p1pp1pb1/bn2Qnp1/2qPN3/1p2P3/2N5/PPPBBPPP/R3K2R b KQkq - 3 2"
},
{
"depth":1,
"nodes":44,
"fen":"2kr3r/p1ppqpb1/bn2Qnp1/3PN3/1p2P3/2N5/PPPBBPPP/R3K2R b KQ - 3 2"
},
{
"depth":1,
"nodes":39,
"fen":"rnb2k1r/pp1Pbppp/2p5/q7/2B5/8/PPPQNnPP/RNB1K2R w KQ - 3 9"
},
{
"depth":1,
"nodes":9,
"fen":"2r5/3pk3/8/2P5/8/2K5/8/8 w - - 5 4"
},
{
"depth":3,
"nodes":62379,
"fen":"rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8"
},
{
"depth":3,
"nodes":89890,
"fen":"r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10"
},
{
"depth":6,
"nodes":1134888,
"fen":"3k4/3p4/8/K1P4r/8/8/8/8 b - - 0 1"
},
{
"depth":6,
"nodes":1015133,
"fen":"8/8/4k3/8/2p5/8/B2P2K1/8 w - - 0 1"
},
{
"depth":6,
"nodes":1440467,
"fen":"8/8/1k6/2b5/2pP4/8/5K2/8 b - d3 0 1"
},
{
"depth":6,
"nodes":661072,
"fen":"5k2/8/8/8/8/8/8/4K2R w K - 0 1"
},
{
"depth":6,
"nodes":803711,
"fen":"3k4/8/8/8/8/8/8/R3K3 w Q - 0 1"
},
{
"depth":4,
"nodes":1274206,
"fen":"r3k2r/1b4bq/8/8/8/8/7B/R3K2R w KQkq - 0 1"
},
{
"depth":4,
"nodes":1720476,
"fen":"r3k2r/8/3Q4/8/8/5q2/8/R3K2R b KQkq - 0 1"
},
{
"depth":6,
"nodes":3821001,
"fen":"2K2r2/4P3/8/8/8/8/8/3k4 w - - 0 1"
},
{
"depth":5,
"nodes":1004658,
"fen":"8/8/1P2K3/8/2n5/1q6/8/5k2 b - - 0 1"
},
{
"depth":6,
"nodes":217342,
"fen":"4k3/1P6/8/8/8/8/K7/8 w - - 0 1"
},
{
"depth":6,
"nodes":92683,
"fen":"8/P1k5/K7/8/8/8/8/8 w - - 0 1"
},
{
"depth":6,
"nodes":2217,
"fen":"K1k5/8/P7/8/8/8/8/8 w - - 0 1"
},
{
"depth":7,
"nodes":567584,
"fen":"8/k1P5/8/1K6/8/8/8/8 w - - 0 1"
},
{
"depth":4,
"nodes":23527,
"fen":"8/8/2k5/5q2/5n2/8/5K2/8 b - - 0 1"
}
]

80
perft/scripts/check-positions Executable file
View file

@ -0,0 +1,80 @@
#!/usr/bin/env python3
# Eryn Wells <eryn@erynwells.me>
'''
New script.
'''
import argparse
import json
import subprocess
def run_perft(fen, depth, expected_nodes_count):
result = subprocess.run(
[
'cargo',
'run',
'--',
'--fen', fen,
str(depth)
],
capture_output=True,
check=True,
text=True
)
nodes_count = 0
for line in result.stdout.splitlines():
if line.startswith('nodes='):
(_, nodes_count) = line.split('=')
nodes_count = int(nodes_count)
return nodes_count
def parse_args(argv, *a, **kw):
parser = argparse.ArgumentParser(*a, **kw)
parser.add_argument('-c', '--continue', dest='should_continue',
action='store_true')
parser.add_argument('file')
args = parser.parse_args(argv)
return args
def main(argv):
args = parse_args(argv[1:], prog=argv[0])
items = []
with open(args.file, 'r') as f:
items = json.load(f)
should_continue = args.should_continue
for item in items:
fen = item['fen']
depth = item['depth']
expected_nodes_count = int(item['nodes'])
print('---')
print(f'fen={fen}')
print(f'expected-nodes={expected_nodes_count}')
nodes_count = run_perft(fen, depth, expected_nodes_count)
print(f'nodes={nodes_count}')
did_pass = nodes_count == expected_nodes_count
if did_pass:
print('result=PASS')
else:
print('result=FAIL')
if not did_pass and not should_continue:
return -1
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))