FA-82796 / Chess move legality / Open access
Promotion check evaluated as a pawn · case 01
b7-b8=Q with the king on e8 is classified "none".
ROOT CAUSE
The promotion letter is ignored, so the new queen still attacks like a pawn.
VERIFIED REPAIR
Replace the pawn with the promoted piece in the mover's colour before classifying.
Unsuccessful approach: Using the raw lower-case letter turns a white promotion into a black piece and targets the wrong king.
Case contract
Input: {"board", "move": [from, to] or [from, to, promotion letter]}. Apply the move (promotion letter becomes a piece of the mover's colour) and classify the check it gives to the enemy king: "direct" (the moved piece attacks it), "discovered" (another of the mover's pieces now attacks it), "double" (both) or "none". Pawns attack diagonally forward, sliders need a clear path.
Why this case matters
SAN "+" suffixes and double-check rules both depend on this classification.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
b=dict(x['board']); fr,to=x['move'][:2]; p=b.pop(fr)
pass
b[to]=p
white=p.isupper()
ks=[s for s,v in b.items() if v==('k' if white else 'K')][0]
def hits(src, tgt):
v=b[src]; t=v.upper()
f,r=ord(src[0])-97,int(src[1])-1
tf,tr=ord(tgt[0])-97,int(tgt[1])-1
df,dr=tf-f,tr-r
if t=='P': return abs(df)==1 and dr==(1 if v.isupper() else -1)
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 in ('R','Q') and orth) or (t in ('B','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
direct=hits(to,ks)
disc=any(hits(s,ks) for s,v in b.items() if s!=to and v.isupper()==white and v.upper()!='K')
if direct and disc: return 'double'
if direct: return 'direct'
if disc: return 'discovered'
return 'none'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),
('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
'direct'),
('defender rook on own king line',
{'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
('black discovered',
{'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
'direct'),
('defender rook on own king line',
{'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
('black discovered',
{'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),
('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
('white piece near own line',
{'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
('white piece near own line',
{'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')]]
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 |
|---|---|---|---|
| promotion gives check | none | direct | Failed |
| knight promotion check | none | direct | Failed |
| simple direct | direct | direct | Passed |
| discovered by bishop | discovered | discovered | Passed |
| double check | double | double | Passed |
| queen diagonal direct | direct | direct | Passed |
| rook lands on king diagonal | none | none | Passed |
| rook quiet | none | none | Passed |
SHA-256 / 30cb71c97610bd5c71f1954224947216675c873a382d90c1b2e8a8d7cf86fe82
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
b=dict(x['board']); fr,to=x['move'][:2]; p=b.pop(fr)
if len(x['move'])>2: p=x['move'][2]
b[to]=p
white=p.isupper()
ks=[s for s,v in b.items() if v==('k' if white else 'K')][0]
def hits(src, tgt):
v=b[src]; t=v.upper()
f,r=ord(src[0])-97,int(src[1])-1
tf,tr=ord(tgt[0])-97,int(tgt[1])-1
df,dr=tf-f,tr-r
if t=='P': return abs(df)==1 and dr==(1 if v.isupper() else -1)
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 in ('R','Q') and orth) or (t in ('B','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
direct=hits(to,ks)
disc=any(hits(s,ks) for s,v in b.items() if s!=to and v.isupper()==white and v.upper()!='K')
if direct and disc: return 'double'
if direct: return 'direct'
if disc: return 'discovered'
return 'none'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),
('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
'direct'),
('defender rook on own king line',
{'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
('black discovered',
{'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
'direct'),
('defender rook on own king line',
{'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
('black discovered',
{'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),
('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
('white piece near own line',
{'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
('white piece near own line',
{'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')]]
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 |
|---|---|---|---|
| promotion gives check | none | direct | Failed |
| knight promotion check | none | direct | Failed |
| simple direct | direct | direct | Passed |
| discovered by bishop | discovered | discovered | Passed |
| double check | double | double | Passed |
| queen diagonal direct | direct | direct | Passed |
| rook lands on king diagonal | none | none | Passed |
| rook quiet | none | none | Passed |
SHA-256 / 52af2124975c6cd783294ef5bbd30c9200c6621df1edcf34db8881439daa83f2
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
b=dict(x['board']); fr,to=x['move'][:2]; p=b.pop(fr)
if len(x['move'])>2: p=x['move'][2].upper() if p.isupper() else x['move'][2].lower()
b[to]=p
white=p.isupper()
ks=[s for s,v in b.items() if v==('k' if white else 'K')][0]
def hits(src, tgt):
v=b[src]; t=v.upper()
f,r=ord(src[0])-97,int(src[1])-1
tf,tr=ord(tgt[0])-97,int(tgt[1])-1
df,dr=tf-f,tr-r
if t=='P': return abs(df)==1 and dr==(1 if v.isupper() else -1)
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 in ('R','Q') and orth) or (t in ('B','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
direct=hits(to,ks)
disc=any(hits(s,ks) for s,v in b.items() if s!=to and v.isupper()==white and v.upper()!='K')
if direct and disc: return 'double'
if direct: return 'direct'
if disc: return 'discovered'
return 'none'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),
('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
'direct'),
('defender rook on own king line',
{'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
('black discovered',
{'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
'direct'),
('defender rook on own king line',
{'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
('black discovered',
{'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),
('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
('white piece near own line',
{'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
('white piece near own line',
{'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
'discovered')],
[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
'direct'),
('knight promotion check',
{'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
('discovered by bishop',
{'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
'double'),
('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
'direct'),
('rook lands on king diagonal',
{'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')]]
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 |
|---|---|---|---|
| promotion gives check | direct | direct | Passed |
| knight promotion check | direct | direct | Passed |
| simple direct | direct | direct | Passed |
| discovered by bishop | discovered | discovered | Passed |
| double check | double | double | Passed |
| queen diagonal direct | direct | direct | Passed |
| rook lands on king diagonal | none | none | Passed |
| rook quiet | none | none | Passed |
SHA-256 / 4921dc0ad8db5a68d4dde89bbbd1a6171ebcf5c278c05579679c83f6d8484b1e
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:15.376757+00:00.
Case digest / 503d47d155b5783342234dc02cf919d62331a6065242b0543946770627ab4826