FAILURE MAP
← Case archive

FA-82536 / Chess move legality / Open access

File check walked as a diagonal · case 01

Interposing on the checking file is rejected while unrelated diagonal squares are accepted.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The step sign never becomes zero, so a check along a file or rank is walked diagonally.

VERIFIED REPAIR

Use the signum of each coordinate difference, which is zero along a file or rank.

Unsuccessful approach: Defaulting a zero difference to +1 still walks off the checking line.

Case contract

Input: {"board", "move": [from, to]} for a non-king piece whose king may be in check (pins are ignored). Return true if the move is allowed by the check rules: no check means true; double check means false; a single check is answered by capturing the checker or, for a rook, bishop or queen checker, by moving onto a square strictly between it and the king.

Why this case matters

Move validators gate every move in engines, servers and arbiters; accepting an illegal move or rejecting a legal one corrupts the game record.

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['move']; p=b[fr]; white=p.isupper()
    ks=[s for s,v in b.items() if v==('K' if white else 'k')][0]
    def at(f,r): return b.get(chr(97+f)+str(r+1)) if 0<=f<8 and 0<=r<8 else None
    def sq(f,r): return chr(97+f)+str(r+1)
    def attackers(s, by_white):
        f,r=ord(s[0])-97,int(s[1])-1
        P,N,B,R,Q=('PNBRQ' if by_white else 'pnbrq')
        out=[]
        pr=r-1 if by_white else r+1
        for df in (-1,1):
            if at(f+df,pr)==P: out.append(sq(f+df,pr))
        for df,dr in ((1,2),(2,1),(-1,2),(-2,1),(1,-2),(2,-1),(-1,-2),(-2,-1)):
            if at(f+df,r+dr)==N: out.append(sq(f+df,r+dr))
        for df,dr in ((1,0),(-1,0),(0,1),(0,-1),(1,1),(1,-1),(-1,1),(-1,-1)):
            kinds=(R,Q) if df==0 or dr==0 else (B,Q)
            ff,rr=f+df,r+dr
            while 0<=ff<8 and 0<=rr<8:
                v=at(ff,rr)
                if v:
                    if v in kinds: out.append(sq(ff,rr))
                    break
                ff+=df; rr+=dr
        return out
    checkers=attackers(ks, not white)
    if len(checkers)>=2: return False
    if not checkers: return True
    c=checkers[0]
    if to==c: return True
    if b[c].lower() in ('n','p'): return False
    cf,cr=ord(c[0])-97,int(c[1])-1
    kf,kr=ord(ks[0])-97,int(ks[1])-1
    sf=1 if cf>kf else -1; sr=1 if cr>kr else -1
    f,r=kf+sf,kr+sr
    between=[]
    while (f,r)!=(cf,cr) and 0<=f<8 and 0<=r<8:
        between.append(sq(f,r)); f+=sf; r+=sr
    return to in between
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('knight check sidestep piece',
   {'board': {'a8': 'k', 'b2': 'B', 'd3': 'n', 'e1': 'K'}, 'move': ['b2', 'c3']}, False),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('cannot block knight',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'f3': 'n'}, 'move': ['d1', 'e2']}, False),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True)],
 [('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('cannot block knight',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'f3': 'n'}, 'move': ['d1', 'e2']}, False),
  ('double check block',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r', 'f3': 'n'}, 'move': ['d1', 'e2']},
   False),
  ('double check capture one',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']},
   False),
  ('diagonal interpose',
   {'board': {'a5': 'b', 'c1': 'N', 'e1': 'K', 'h8': 'k'}, 'move': ['c1', 'b3']}, False),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('double check capture one',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']},
   False),
  ('diagonal interpose',
   {'board': {'a5': 'b', 'c1': 'N', 'e1': 'K', 'h8': 'k'}, 'move': ['c1', 'b3']}, False),
  ('diagonal interpose d2',
   {'board': {'a5': 'b', 'e1': 'K', 'f3': 'N', 'h8': 'k'}, 'move': ['f3', 'd2']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('black cannot block white knight',
   {'board': {'a1': 'K', 'c8': 'b', 'd6': 'N', 'e8': 'k'}, 'move': ['c8', 'd7']}, False),
  ('irrelevant move in check',
   {'board': {'a2': 'P', 'a8': 'k', 'e1': 'K', 'e8': 'r'}, 'move': ['a2', 'a3']}, False),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('black cannot block white knight',
   {'board': {'a1': 'K', 'c8': 'b', 'd6': 'N', 'e8': 'k'}, 'move': ['c8', 'd7']}, False),
  ('irrelevant move in check',
   {'board': {'a2': 'P', 'a8': 'k', 'e1': 'K', 'e8': 'r'}, 'move': ['a2', 'a3']}, False),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('knight check sidestep piece',
   {'board': {'a8': 'k', 'b2': 'B', 'd3': 'n', 'e1': 'K'}, 'move': ['b2', 'c3']}, False),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)]]
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 fixtureActualExpectedOutcome
no checkTrueTruePassed
block rook checkTrueFalseFailed
interpose on fileFalseTrueFailed
capture rook checkerTrueTruePassed
knight check sidestep pieceFalseFalsePassed
bishop takes knight checkerTrueTruePassed
cannot block knightFalseFalsePassed
black blocks white queenFalseTrueFailed

SHA-256 / 102eee2d2c1f273d1ba7692d96e1768e0bf16a9deea1c9ffe87e86fc161def95

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['move']; p=b[fr]; white=p.isupper()
    ks=[s for s,v in b.items() if v==('K' if white else 'k')][0]
    def at(f,r): return b.get(chr(97+f)+str(r+1)) if 0<=f<8 and 0<=r<8 else None
    def sq(f,r): return chr(97+f)+str(r+1)
    def attackers(s, by_white):
        f,r=ord(s[0])-97,int(s[1])-1
        P,N,B,R,Q=('PNBRQ' if by_white else 'pnbrq')
        out=[]
        pr=r-1 if by_white else r+1
        for df in (-1,1):
            if at(f+df,pr)==P: out.append(sq(f+df,pr))
        for df,dr in ((1,2),(2,1),(-1,2),(-2,1),(1,-2),(2,-1),(-1,-2),(-2,-1)):
            if at(f+df,r+dr)==N: out.append(sq(f+df,r+dr))
        for df,dr in ((1,0),(-1,0),(0,1),(0,-1),(1,1),(1,-1),(-1,1),(-1,-1)):
            kinds=(R,Q) if df==0 or dr==0 else (B,Q)
            ff,rr=f+df,r+dr
            while 0<=ff<8 and 0<=rr<8:
                v=at(ff,rr)
                if v:
                    if v in kinds: out.append(sq(ff,rr))
                    break
                ff+=df; rr+=dr
        return out
    checkers=attackers(ks, not white)
    if len(checkers)>=2: return False
    if not checkers: return True
    c=checkers[0]
    if to==c: return True
    if b[c].lower() in ('n','p'): return False
    cf,cr=ord(c[0])-97,int(c[1])-1
    kf,kr=ord(ks[0])-97,int(ks[1])-1
    sf=(cf-kf)//abs(cf-kf) if cf!=kf else 1; sr=(cr-kr)//abs(cr-kr) if cr!=kr else 1
    f,r=kf+sf,kr+sr
    between=[]
    while (f,r)!=(cf,cr) and 0<=f<8 and 0<=r<8:
        between.append(sq(f,r)); f+=sf; r+=sr
    return to in between
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('knight check sidestep piece',
   {'board': {'a8': 'k', 'b2': 'B', 'd3': 'n', 'e1': 'K'}, 'move': ['b2', 'c3']}, False),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('cannot block knight',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'f3': 'n'}, 'move': ['d1', 'e2']}, False),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True)],
 [('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('cannot block knight',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'f3': 'n'}, 'move': ['d1', 'e2']}, False),
  ('double check block',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r', 'f3': 'n'}, 'move': ['d1', 'e2']},
   False),
  ('double check capture one',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']},
   False),
  ('diagonal interpose',
   {'board': {'a5': 'b', 'c1': 'N', 'e1': 'K', 'h8': 'k'}, 'move': ['c1', 'b3']}, False),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('double check capture one',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']},
   False),
  ('diagonal interpose',
   {'board': {'a5': 'b', 'c1': 'N', 'e1': 'K', 'h8': 'k'}, 'move': ['c1', 'b3']}, False),
  ('diagonal interpose d2',
   {'board': {'a5': 'b', 'e1': 'K', 'f3': 'N', 'h8': 'k'}, 'move': ['f3', 'd2']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('black cannot block white knight',
   {'board': {'a1': 'K', 'c8': 'b', 'd6': 'N', 'e8': 'k'}, 'move': ['c8', 'd7']}, False),
  ('irrelevant move in check',
   {'board': {'a2': 'P', 'a8': 'k', 'e1': 'K', 'e8': 'r'}, 'move': ['a2', 'a3']}, False),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('black cannot block white knight',
   {'board': {'a1': 'K', 'c8': 'b', 'd6': 'N', 'e8': 'k'}, 'move': ['c8', 'd7']}, False),
  ('irrelevant move in check',
   {'board': {'a2': 'P', 'a8': 'k', 'e1': 'K', 'e8': 'r'}, 'move': ['a2', 'a3']}, False),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('knight check sidestep piece',
   {'board': {'a8': 'k', 'b2': 'B', 'd3': 'n', 'e1': 'K'}, 'move': ['b2', 'c3']}, False),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)]]
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 fixtureActualExpectedOutcome
no checkTrueTruePassed
block rook checkFalseFalsePassed
interpose on fileFalseTrueFailed
capture rook checkerTrueTruePassed
knight check sidestep pieceFalseFalsePassed
bishop takes knight checkerTrueTruePassed
cannot block knightFalseFalsePassed
black blocks white queenFalseTrueFailed

SHA-256 / 04888542ec9ed29266d232cb2259b4e4088c5468eeb27c42adc3d434008fe021

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['move']; p=b[fr]; white=p.isupper()
    ks=[s for s,v in b.items() if v==('K' if white else 'k')][0]
    def at(f,r): return b.get(chr(97+f)+str(r+1)) if 0<=f<8 and 0<=r<8 else None
    def sq(f,r): return chr(97+f)+str(r+1)
    def attackers(s, by_white):
        f,r=ord(s[0])-97,int(s[1])-1
        P,N,B,R,Q=('PNBRQ' if by_white else 'pnbrq')
        out=[]
        pr=r-1 if by_white else r+1
        for df in (-1,1):
            if at(f+df,pr)==P: out.append(sq(f+df,pr))
        for df,dr in ((1,2),(2,1),(-1,2),(-2,1),(1,-2),(2,-1),(-1,-2),(-2,-1)):
            if at(f+df,r+dr)==N: out.append(sq(f+df,r+dr))
        for df,dr in ((1,0),(-1,0),(0,1),(0,-1),(1,1),(1,-1),(-1,1),(-1,-1)):
            kinds=(R,Q) if df==0 or dr==0 else (B,Q)
            ff,rr=f+df,r+dr
            while 0<=ff<8 and 0<=rr<8:
                v=at(ff,rr)
                if v:
                    if v in kinds: out.append(sq(ff,rr))
                    break
                ff+=df; rr+=dr
        return out
    checkers=attackers(ks, not white)
    if len(checkers)>=2: return False
    if not checkers: return True
    c=checkers[0]
    if to==c: return True
    if b[c].lower() in ('n','p'): return False
    cf,cr=ord(c[0])-97,int(c[1])-1
    kf,kr=ord(ks[0])-97,int(ks[1])-1
    sf=(cf>kf)-(cf<kf); sr=(cr>kr)-(cr<kr)
    f,r=kf+sf,kr+sr
    between=[]
    while (f,r)!=(cf,cr) and 0<=f<8 and 0<=r<8:
        between.append(sq(f,r)); f+=sf; r+=sr
    return to in between
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('knight check sidestep piece',
   {'board': {'a8': 'k', 'b2': 'B', 'd3': 'n', 'e1': 'K'}, 'move': ['b2', 'c3']}, False),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('cannot block knight',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'f3': 'n'}, 'move': ['d1', 'e2']}, False),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True)],
 [('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('cannot block knight',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'f3': 'n'}, 'move': ['d1', 'e2']}, False),
  ('double check block',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r', 'f3': 'n'}, 'move': ['d1', 'e2']},
   False),
  ('double check capture one',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']},
   False),
  ('diagonal interpose',
   {'board': {'a5': 'b', 'c1': 'N', 'e1': 'K', 'h8': 'k'}, 'move': ['c1', 'b3']}, False),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('double check capture one',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']},
   False),
  ('diagonal interpose',
   {'board': {'a5': 'b', 'c1': 'N', 'e1': 'K', 'h8': 'k'}, 'move': ['c1', 'b3']}, False),
  ('diagonal interpose d2',
   {'board': {'a5': 'b', 'e1': 'K', 'f3': 'N', 'h8': 'k'}, 'move': ['f3', 'd2']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('black cannot block white knight',
   {'board': {'a1': 'K', 'c8': 'b', 'd6': 'N', 'e8': 'k'}, 'move': ['c8', 'd7']}, False),
  ('irrelevant move in check',
   {'board': {'a2': 'P', 'a8': 'k', 'e1': 'K', 'e8': 'r'}, 'move': ['a2', 'a3']}, False),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('black cannot block white knight',
   {'board': {'a1': 'K', 'c8': 'b', 'd6': 'N', 'e8': 'k'}, 'move': ['c8', 'd7']}, False),
  ('irrelevant move in check',
   {'board': {'a2': 'P', 'a8': 'k', 'e1': 'K', 'e8': 'r'}, 'move': ['a2', 'a3']}, False),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)],
 [('no check', {'board': {'b1': 'N', 'e1': 'K', 'e8': 'k'}, 'move': ['b1', 'c3']}, True),
  ('block rook check',
   {'board': {'a8': 'k', 'b1': 'N', 'e1': 'K', 'e8': 'r'}, 'move': ['b1', 'c3']}, False),
  ('interpose on file',
   {'board': {'a8': 'k', 'd1': 'Q', 'e1': 'K', 'e8': 'r'}, 'move': ['d1', 'e2']}, True),
  ('capture rook checker',
   {'board': {'a8': 'k', 'e1': 'K', 'e8': 'r', 'h8': 'R'}, 'move': ['h8', 'e8']}, True),
  ('knight check sidestep piece',
   {'board': {'a8': 'k', 'b2': 'B', 'd3': 'n', 'e1': 'K'}, 'move': ['b2', 'c3']}, False),
  ('bishop takes knight checker',
   {'board': {'a8': 'k', 'e1': 'K', 'f3': 'n', 'g2': 'B'}, 'move': ['g2', 'f3']}, True),
  ('black blocks white queen',
   {'board': {'a1': 'K', 'c6': 'n', 'e1': 'Q', 'e8': 'k'}, 'move': ['c6', 'e7']}, True),
  ('rank check interpose',
   {'board': {'a1': 'K', 'a8': 'k', 'b3': 'N', 'h1': 'q'}, 'move': ['b3', 'c1']}, True)]]
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 fixtureActualExpectedOutcome
no checkTrueTruePassed
block rook checkFalseFalsePassed
interpose on fileTrueTruePassed
capture rook checkerTrueTruePassed
knight check sidestep pieceFalseFalsePassed
bishop takes knight checkerTrueTruePassed
cannot block knightFalseFalsePassed
black blocks white queenTrueTruePassed

SHA-256 / b4f53b02ce4e299b631a10e342696a1216f452722661fbd243db3be69485e867

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:13.050174+00:00.

Case digest / dc6009a17e37b230d0cbb969d55ba9b3321d07d29fc8a5ccd16d45b0a5ae9021