FA-82681 / Chess move legality / Open access
Queen twin on a diagonal not detected · case 01
Qa1-d4 with another queen able to reach d4 diagonally is written without a disambiguator.
ROOT CAUSE
Competing queens are only tested along ranks and files.
VERIFIED REPAIR
A queen reaches along ranks, files and diagonals.
Unsuccessful approach: Testing only diagonals misses queen twins on ranks and files.
Case contract
Input: {"board", "from", "to"} for a knight, bishop, rook, queen or king move. Return SAN (no check suffix): upper-case piece letter, then a disambiguator only if another same-colour piece of the same type could also reach the target (sliders need a clear path): the origin file if it is unique among those pieces, else the origin rank if unique, else the full origin square; then "x" if the target is occupied; then the target.
Why this case matters
Exported PGN must be re-readable; a wrong disambiguator makes the game unreplayable.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
b=x['board']; fr,to=x['from'],x['to']; p=b[fr]; white=p.isupper()
def c(q): return ord(q[0])-97,int(q[1])-1
def reach(q):
f,r=c(q); tf,tr=c(to); df,dr=tf-f,tr-r
t=p.upper()
if t=='N': return (abs(df),abs(dr)) in ((1,2),(2,1))
if t=='K': return max(abs(df),abs(dr))==1
orth=(df==0)!=(dr==0); diag=abs(df)==abs(dr) and df!=0
if not ((t=='R' and orth) or (t=='B' and diag) or (t=='Q' and orth)): return False
sf=(df>0)-(df<0); sr=(dr>0)-(dr<0)
cf,cr=f+sf,r+sr
while (cf,cr)!=(tf,tr):
if chr(97+cf)+str(cr+1) in b: return False
cf+=sf; cr+=sr
return True
others=[q for q,v in b.items() if v==p and q!=fr and reach(q)]
dis=''
if others:
if all(q[0]!=fr[0] for q in others): dis=fr[0]
elif all(q[1]!=fr[1] for q in others): dis=fr[1]
else: dis=fr
cap='x' if to in b else ''
return p.upper()+dis+cap+to
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4')],
[('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('capture with file',
{'board': {'a1': 'K', 'a8': 'k', 'c3': 'N', 'e4': 'p', 'g3': 'N'}, 'from': 'c3', 'to': 'e4'},
'Ncxe4'),
('simple bishop', {'board': {'c1': 'B', 'e1': 'K', 'e8': 'k'}, 'from': 'c1', 'to': 'g5'}, 'Bg5'),
('rooks on same rank',
{'board': {'a1': 'R', 'f1': 'R', 'h2': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd1'}, 'Rad1')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('capture with file',
{'board': {'a1': 'K', 'a8': 'k', 'c3': 'N', 'e4': 'p', 'g3': 'N'}, 'from': 'c3', 'to': 'e4'},
'Ncxe4'),
('simple bishop', {'board': {'c1': 'B', 'e1': 'K', 'e8': 'k'}, 'from': 'c1', 'to': 'g5'}, 'Bg5'),
('rooks on same rank',
{'board': {'a1': 'R', 'f1': 'R', 'h2': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd1'}, 'Rad1'),
('rook shielded by bishop',
{'board': {'a4': 'R', 'a8': 'k', 'c4': 'B', 'h1': 'K', 'h4': 'R'}, 'from': 'h4', 'to': 'd4'},
'Rd4')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('rook shielded by bishop',
{'board': {'a4': 'R', 'a8': 'k', 'c4': 'B', 'h1': 'K', 'h4': 'R'}, 'from': 'h4', 'to': 'd4'},
'Rd4')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4')]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'error:' + type(exc).__name__
check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| two knights different files | Nbd2 | Nbd2 | Passed |
| two rooks same file | R1a3 | R1a3 | Passed |
| three queens need square | Qh4e1 | Qh4e1 | Passed |
| blocked rook no disambiguation | Rd1 | Rd1 | Passed |
| enemy knight irrelevant | Nd2 | Nd2 | Passed |
| black knights | Nbd7 | Nbd7 | Passed |
| black rook capture | Rxa2 | Rxa2 | Passed |
| queen diagonal twin | Qd4 | Qad4 | Failed |
SHA-256 / 77139f6b6b01a065c1dbe062a0cefff5c2b38377bd0b2d13d3729385b3569900
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
b=x['board']; fr,to=x['from'],x['to']; p=b[fr]; white=p.isupper()
def c(q): return ord(q[0])-97,int(q[1])-1
def reach(q):
f,r=c(q); tf,tr=c(to); df,dr=tf-f,tr-r
t=p.upper()
if t=='N': return (abs(df),abs(dr)) in ((1,2),(2,1))
if t=='K': return max(abs(df),abs(dr))==1
orth=(df==0)!=(dr==0); diag=abs(df)==abs(dr) and df!=0
if not ((t=='R' and orth) or (t=='B' and diag) or (t=='Q' and diag)): return False
sf=(df>0)-(df<0); sr=(dr>0)-(dr<0)
cf,cr=f+sf,r+sr
while (cf,cr)!=(tf,tr):
if chr(97+cf)+str(cr+1) in b: return False
cf+=sf; cr+=sr
return True
others=[q for q,v in b.items() if v==p and q!=fr and reach(q)]
dis=''
if others:
if all(q[0]!=fr[0] for q in others): dis=fr[0]
elif all(q[1]!=fr[1] for q in others): dis=fr[1]
else: dis=fr
cap='x' if to in b else ''
return p.upper()+dis+cap+to
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4')],
[('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('capture with file',
{'board': {'a1': 'K', 'a8': 'k', 'c3': 'N', 'e4': 'p', 'g3': 'N'}, 'from': 'c3', 'to': 'e4'},
'Ncxe4'),
('simple bishop', {'board': {'c1': 'B', 'e1': 'K', 'e8': 'k'}, 'from': 'c1', 'to': 'g5'}, 'Bg5'),
('rooks on same rank',
{'board': {'a1': 'R', 'f1': 'R', 'h2': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd1'}, 'Rad1')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('capture with file',
{'board': {'a1': 'K', 'a8': 'k', 'c3': 'N', 'e4': 'p', 'g3': 'N'}, 'from': 'c3', 'to': 'e4'},
'Ncxe4'),
('simple bishop', {'board': {'c1': 'B', 'e1': 'K', 'e8': 'k'}, 'from': 'c1', 'to': 'g5'}, 'Bg5'),
('rooks on same rank',
{'board': {'a1': 'R', 'f1': 'R', 'h2': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd1'}, 'Rad1'),
('rook shielded by bishop',
{'board': {'a4': 'R', 'a8': 'k', 'c4': 'B', 'h1': 'K', 'h4': 'R'}, 'from': 'h4', 'to': 'd4'},
'Rd4')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('rook shielded by bishop',
{'board': {'a4': 'R', 'a8': 'k', 'c4': 'B', 'h1': 'K', 'h4': 'R'}, 'from': 'h4', 'to': 'd4'},
'Rd4')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4')]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'error:' + type(exc).__name__
check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| two knights different files | Nbd2 | Nbd2 | Passed |
| two rooks same file | R1a3 | R1a3 | Passed |
| three queens need square | Qe1 | Qh4e1 | Failed |
| blocked rook no disambiguation | Rd1 | Rd1 | Passed |
| enemy knight irrelevant | Nd2 | Nd2 | Passed |
| black knights | Nbd7 | Nbd7 | Passed |
| black rook capture | Rxa2 | Rxa2 | Passed |
| queen diagonal twin | Qad4 | Qad4 | Passed |
SHA-256 / 72dd1a017e07b320d0980e5d1a7620c9a054a4cb1ba4ffc6ae3eeee3d5778bad
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
b=x['board']; fr,to=x['from'],x['to']; p=b[fr]; white=p.isupper()
def c(q): return ord(q[0])-97,int(q[1])-1
def reach(q):
f,r=c(q); tf,tr=c(to); df,dr=tf-f,tr-r
t=p.upper()
if t=='N': return (abs(df),abs(dr)) in ((1,2),(2,1))
if t=='K': return max(abs(df),abs(dr))==1
orth=(df==0)!=(dr==0); diag=abs(df)==abs(dr) and df!=0
if not ((t=='R' and orth) or (t=='B' and diag) or (t=='Q' and (orth or diag))): return False
sf=(df>0)-(df<0); sr=(dr>0)-(dr<0)
cf,cr=f+sf,r+sr
while (cf,cr)!=(tf,tr):
if chr(97+cf)+str(cr+1) in b: return False
cf+=sf; cr+=sr
return True
others=[q for q,v in b.items() if v==p and q!=fr and reach(q)]
dis=''
if others:
if all(q[0]!=fr[0] for q in others): dis=fr[0]
elif all(q[1]!=fr[1] for q in others): dis=fr[1]
else: dis=fr
cap='x' if to in b else ''
return p.upper()+dis+cap+to
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4')],
[('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('capture with file',
{'board': {'a1': 'K', 'a8': 'k', 'c3': 'N', 'e4': 'p', 'g3': 'N'}, 'from': 'c3', 'to': 'e4'},
'Ncxe4'),
('simple bishop', {'board': {'c1': 'B', 'e1': 'K', 'e8': 'k'}, 'from': 'c1', 'to': 'g5'}, 'Bg5'),
('rooks on same rank',
{'board': {'a1': 'R', 'f1': 'R', 'h2': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd1'}, 'Rad1')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('capture with file',
{'board': {'a1': 'K', 'a8': 'k', 'c3': 'N', 'e4': 'p', 'g3': 'N'}, 'from': 'c3', 'to': 'e4'},
'Ncxe4'),
('simple bishop', {'board': {'c1': 'B', 'e1': 'K', 'e8': 'k'}, 'from': 'c1', 'to': 'g5'}, 'Bg5'),
('rooks on same rank',
{'board': {'a1': 'R', 'f1': 'R', 'h2': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd1'}, 'Rad1'),
('rook shielded by bishop',
{'board': {'a4': 'R', 'a8': 'k', 'c4': 'B', 'h1': 'K', 'h4': 'R'}, 'from': 'h4', 'to': 'd4'},
'Rd4')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4'),
('rook shielded by bishop',
{'board': {'a4': 'R', 'a8': 'k', 'c4': 'B', 'h1': 'K', 'h4': 'R'}, 'from': 'h4', 'to': 'd4'},
'Rd4')],
[('two knights different files',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'N'}, 'from': 'b1', 'to': 'd2'}, 'Nbd2'),
('two rooks same file',
{'board': {'a1': 'R', 'a5': 'R', 'e1': 'K', 'e8': 'k'}, 'from': 'a1', 'to': 'a3'}, 'R1a3'),
('three queens need square',
{'board': {'a1': 'K', 'a8': 'k', 'e4': 'Q', 'h1': 'Q', 'h4': 'Q'}, 'from': 'h4', 'to': 'e1'},
'Qh4e1'),
('blocked rook no disambiguation',
{'board': {'a1': 'R', 'c1': 'B', 'e2': 'K', 'e8': 'k', 'h1': 'R'}, 'from': 'h1', 'to': 'd1'},
'Rd1'),
('enemy knight irrelevant',
{'board': {'b1': 'N', 'e1': 'K', 'e8': 'k', 'f3': 'n'}, 'from': 'b1', 'to': 'd2'}, 'Nd2'),
('black knights',
{'board': {'b8': 'n', 'e1': 'K', 'e8': 'k', 'f6': 'n'}, 'from': 'b8', 'to': 'd7'}, 'Nbd7'),
('black rook capture',
{'board': {'a2': 'P', 'a8': 'r', 'e1': 'K', 'e8': 'k'}, 'from': 'a8', 'to': 'a2'}, 'Rxa2'),
('queen diagonal twin',
{'board': {'a1': 'Q', 'g1': 'Q', 'h1': 'K', 'h8': 'k'}, 'from': 'a1', 'to': 'd4'}, 'Qad4')]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'error:' + type(exc).__name__
check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| two knights different files | Nbd2 | Nbd2 | Passed |
| two rooks same file | R1a3 | R1a3 | Passed |
| three queens need square | Qh4e1 | Qh4e1 | Passed |
| blocked rook no disambiguation | Rd1 | Rd1 | Passed |
| enemy knight irrelevant | Nd2 | Nd2 | Passed |
| black knights | Nbd7 | Nbd7 | Passed |
| black rook capture | Rxa2 | Rxa2 | Passed |
| queen diagonal twin | Qad4 | Qad4 | Passed |
SHA-256 / c5ada391da159aebc57d30bef7a4b090557826cff647d523389ecac54a0e78c7
Verification & scope
A deterministic toy model with an explicitly stated contract; boards are {square: piece} with white upper-case and black lower-case pieces; no claim of full FIDE Laws conformance. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:50:14.466305+00:00.
Case digest / 5aa00b298629792ea3c591fab0b86262a7fccf28c53a9db1427664a5350c4d13