FA-82351 / Chess move legality / Open access
Knight captures its own side but not the enemy · case 01
The knight may land on a friendly bishop but not capture an enemy pawn.
ROOT CAUSE
The colour comparison in the occupancy filter is inverted.
VERIFIED REPAIR
Skip targets occupied by a piece of the knight's own colour.
Unsuccessful approach: Skipping only identical pieces lets the knight capture friendly pieces of other types.
Case contract
Input: {"board": {square: piece}, "from": square of a knight}. Squares are indexed 0..63 with a1=0, h1=7, a8=56. Return the sorted list of pseudo-legal knight destinations: on the board, not wrapping across the a/h file edge, and not occupied by a piece of the knight's colour.
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):
def idx(s): return (int(s[1])-1)*8 + ord(s[0])-97
def name(i): return 'abcdefgh'[i%8]+str(i//8+1)
b=x['board']; f=idx(x['from']); me=b[x['from']]
out=[]
for d in (6,10,15,17,-6,-10,-15,-17):
t=f+d
if t<0 or t>63: continue
if abs(t%8-f%8)>2: continue
occ=b.get(name(t))
if occ and occ.isupper()!=me.isupper(): continue
out.append(name(t))
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('top rank knight', {'board': {'c7': 'N'}, 'from': 'c7'}, ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'])],
[('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('top rank knight', {'board': {'c7': 'N'}, 'from': 'c7'}, ['a6', 'a8', 'b5', 'd5', 'e6', 'e8']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4']),
('knight c2 reaches a1 area', {'board': {'c2': 'n'}, 'from': 'c2'},
['a1', 'a3', 'b4', 'd4', 'e1', 'e3']),
('knight on c8', {'board': {'c8': 'n'}, 'from': 'c8'}, ['a7', 'b6', 'd6', 'e7'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4']),
('knight c2 reaches a1 area', {'board': {'c2': 'n'}, 'from': 'c2'},
['a1', 'a3', 'b4', 'd4', 'e1', 'e3']),
('knight on c8', {'board': {'c8': 'n'}, 'from': 'c8'}, ['a7', 'b6', 'd6', 'e7']),
('knight on b7', {'board': {'b7': 'N'}, 'from': 'b7'}, ['a5', 'c5', 'd6', 'd8'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4'])]]
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 |
|---|---|---|---|
| corner a1 | ['b3', 'c2'] | ['b3', 'c2'] | Passed |
| h-file knight | ['f2', 'f4', 'g1', 'g5'] | ['f2', 'f4', 'g1', 'g5'] | Passed |
| g-file knight | ['e4', 'e6', 'f3', 'f7', 'h3', 'h7'] | ['e4', 'e6', 'f3', 'f7', 'h3', 'h7'] | Passed |
| b-file knight | ['a2', 'a6', 'c2', 'c6', 'd3', 'd5'] | ['a2', 'a6', 'c2', 'c6', 'd3', 'd5'] | Passed |
| centre with own and enemy | ['b3', 'b5', 'c2', 'e2', 'e6', 'f3', 'f5'] | ['b3', 'b5', 'c2', 'c6', 'e2', 'f3'] | Failed |
| black knight own pieces | ['c4', 'c6', 'd3', 'd7', 'f7', 'g4', 'g6'] | ['c6', 'd3', 'f3', 'f7', 'g4', 'g6'] | Failed |
| h8 corner | ['f7', 'g6'] | ['f7', 'g6'] | Passed |
| top rank knight | ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'] | ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'] | Passed |
SHA-256 / 9d4cb334a56f2444027eb0492ac90273ebda6159e149800663131c2a0a8d06f8
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
def idx(s): return (int(s[1])-1)*8 + ord(s[0])-97
def name(i): return 'abcdefgh'[i%8]+str(i//8+1)
b=x['board']; f=idx(x['from']); me=b[x['from']]
out=[]
for d in (6,10,15,17,-6,-10,-15,-17):
t=f+d
if t<0 or t>63: continue
if abs(t%8-f%8)>2: continue
occ=b.get(name(t))
if occ and occ==me: continue
out.append(name(t))
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('top rank knight', {'board': {'c7': 'N'}, 'from': 'c7'}, ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'])],
[('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('top rank knight', {'board': {'c7': 'N'}, 'from': 'c7'}, ['a6', 'a8', 'b5', 'd5', 'e6', 'e8']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4']),
('knight c2 reaches a1 area', {'board': {'c2': 'n'}, 'from': 'c2'},
['a1', 'a3', 'b4', 'd4', 'e1', 'e3']),
('knight on c8', {'board': {'c8': 'n'}, 'from': 'c8'}, ['a7', 'b6', 'd6', 'e7'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4']),
('knight c2 reaches a1 area', {'board': {'c2': 'n'}, 'from': 'c2'},
['a1', 'a3', 'b4', 'd4', 'e1', 'e3']),
('knight on c8', {'board': {'c8': 'n'}, 'from': 'c8'}, ['a7', 'b6', 'd6', 'e7']),
('knight on b7', {'board': {'b7': 'N'}, 'from': 'b7'}, ['a5', 'c5', 'd6', 'd8'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4'])]]
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 |
|---|---|---|---|
| corner a1 | ['b3', 'c2'] | ['b3', 'c2'] | Passed |
| h-file knight | ['f2', 'f4', 'g1', 'g5'] | ['f2', 'f4', 'g1', 'g5'] | Passed |
| g-file knight | ['e4', 'e6', 'f3', 'f7', 'h3', 'h7'] | ['e4', 'e6', 'f3', 'f7', 'h3', 'h7'] | Passed |
| b-file knight | ['a2', 'a6', 'c2', 'c6', 'd3', 'd5'] | ['a2', 'a6', 'c2', 'c6', 'd3', 'd5'] | Passed |
| centre with own and enemy | ['b3', 'b5', 'c2', 'c6', 'e2', 'e6', 'f3', 'f5'] | ['b3', 'b5', 'c2', 'c6', 'e2', 'f3'] | Failed |
| black knight own pieces | ['c4', 'c6', 'd3', 'd7', 'f3', 'f7', 'g4', 'g6'] | ['c6', 'd3', 'f3', 'f7', 'g4', 'g6'] | Failed |
| h8 corner | ['f7', 'g6'] | ['f7', 'g6'] | Passed |
| top rank knight | ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'] | ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'] | Passed |
SHA-256 / e6e36948e0bd5793473e7f73366b96ca165e6c045ef3909e66c680076b254a26
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
def idx(s): return (int(s[1])-1)*8 + ord(s[0])-97
def name(i): return 'abcdefgh'[i%8]+str(i//8+1)
b=x['board']; f=idx(x['from']); me=b[x['from']]
out=[]
for d in (6,10,15,17,-6,-10,-15,-17):
t=f+d
if t<0 or t>63: continue
if abs(t%8-f%8)>2: continue
occ=b.get(name(t))
if occ and occ.isupper()==me.isupper(): continue
out.append(name(t))
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('top rank knight', {'board': {'c7': 'N'}, 'from': 'c7'}, ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'])],
[('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('top rank knight', {'board': {'c7': 'N'}, 'from': 'c7'}, ['a6', 'a8', 'b5', 'd5', 'e6', 'e8']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4']),
('knight c2 reaches a1 area', {'board': {'c2': 'n'}, 'from': 'c2'},
['a1', 'a3', 'b4', 'd4', 'e1', 'e3']),
('knight on c8', {'board': {'c8': 'n'}, 'from': 'c8'}, ['a7', 'b6', 'd6', 'e7'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4']),
('knight c2 reaches a1 area', {'board': {'c2': 'n'}, 'from': 'c2'},
['a1', 'a3', 'b4', 'd4', 'e1', 'e3']),
('knight on c8', {'board': {'c8': 'n'}, 'from': 'c8'}, ['a7', 'b6', 'd6', 'e7']),
('knight on b7', {'board': {'b7': 'N'}, 'from': 'b7'}, ['a5', 'c5', 'd6', 'd8'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('knight to a1 from b3', {'board': {'a1': 'r', 'b3': 'N'}, 'from': 'b3'},
['a1', 'a5', 'c1', 'c5', 'd2', 'd4']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4'])],
[('corner a1', {'board': {'a1': 'N'}, 'from': 'a1'}, ['b3', 'c2']),
('h-file knight', {'board': {'h3': 'N'}, 'from': 'h3'}, ['f2', 'f4', 'g1', 'g5']),
('g-file knight', {'board': {'g5': 'n'}, 'from': 'g5'}, ['e4', 'e6', 'f3', 'f7', 'h3', 'h7']),
('b-file knight', {'board': {'b4': 'N'}, 'from': 'b4'}, ['a2', 'a6', 'c2', 'c6', 'd3', 'd5']),
('centre with own and enemy',
{'board': {'c6': 'p', 'd4': 'N', 'e6': 'P', 'f5': 'B'}, 'from': 'd4'},
['b3', 'b5', 'c2', 'c6', 'e2', 'f3']),
('black knight own pieces', {'board': {'c4': 'q', 'd7': 'p', 'e5': 'n', 'f3': 'P'}, 'from': 'e5'},
['c6', 'd3', 'f3', 'f7', 'g4', 'g6']),
('h8 corner', {'board': {'h8': 'n'}, 'from': 'h8'}, ['f7', 'g6']),
('knight on g2', {'board': {'e1': 'Q', 'g2': 'N'}, 'from': 'g2'}, ['e3', 'f4', 'h4'])]]
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 |
|---|---|---|---|
| corner a1 | ['b3', 'c2'] | ['b3', 'c2'] | Passed |
| h-file knight | ['f2', 'f4', 'g1', 'g5'] | ['f2', 'f4', 'g1', 'g5'] | Passed |
| g-file knight | ['e4', 'e6', 'f3', 'f7', 'h3', 'h7'] | ['e4', 'e6', 'f3', 'f7', 'h3', 'h7'] | Passed |
| b-file knight | ['a2', 'a6', 'c2', 'c6', 'd3', 'd5'] | ['a2', 'a6', 'c2', 'c6', 'd3', 'd5'] | Passed |
| centre with own and enemy | ['b3', 'b5', 'c2', 'c6', 'e2', 'f3'] | ['b3', 'b5', 'c2', 'c6', 'e2', 'f3'] | Passed |
| black knight own pieces | ['c6', 'd3', 'f3', 'f7', 'g4', 'g6'] | ['c6', 'd3', 'f3', 'f7', 'g4', 'g6'] | Passed |
| h8 corner | ['f7', 'g6'] | ['f7', 'g6'] | Passed |
| top rank knight | ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'] | ['a6', 'a8', 'b5', 'd5', 'e6', 'e8'] | Passed |
SHA-256 / 950d56d8e18eb056f1e8a0bf56fe131d0380bf1edf316bb0f4297662bebce402
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:11.415514+00:00.
Case digest / 37769def6297d75bad56654de594808d5b850ed3c91ec0b8dcd6f8d4c02aa7ad