broken_source:
"""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]; cap=b.get(to)
    rights=x['rights'].replace('-','')
    if p=='K': rights=rights.replace('K','').replace('Q','')
    if p=='k': rights=rights.replace('k','').replace('q','')
    for sq,r in (('h1','K'),('a1','Q'),('h8','k'),('a8','q')):
        if fr==sq or to==sq: rights=rights.replace(r,'')
    ep=None
    if p in ('P','p') and abs(int(to[1])-int(fr[1]))==2:
        enemy='p' if p=='P' else 'P'
        f=ord(to[0])-97
        if any(b.get(chr(97+f+d)+to[1])==enemy for d in (-1,1)):
            ep=fr[0]+str((int(fr[1])+int(to[1]))//2)
    pawn_or_capture=p in ('P','p') or cap is not None
    hm=0 if pawn_or_capture else x['halfmove']+1
    return {'rights':rights,'ep':ep,'halfmove':hm}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'})],
 [('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'})],
 [('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'})]]
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)

source:
"""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]; cap=b.get(to)
    rights=x['rights'].replace('-','')
    if p=='K': rights=rights.replace('K','').replace('Q','')
    if p=='k': rights=rights.replace('k','').replace('q','')
    for sq,r in (('h1','K'),('a1','Q'),('h8','k'),('a8','q')):
        if fr==sq or to==sq: rights=rights.replace(r,'')
    ep=None
    if p in ('P','p') and abs(int(to[1])-int(fr[1]))==2:
        enemy='p' if p=='P' else 'P'
        f=ord(to[0])-97
        if any(b.get(chr(97+f+d)+to[1])==enemy for d in (-1,1)):
            ep=fr[0]+str((int(fr[1])+int(to[1]))//2)
    pawn_or_capture=p in ('P','p') or cap is not None
    hm=0 if pawn_or_capture else x['halfmove']+1
    return {'rights':'-' if not x['rights'] else rights,'ep':ep,'halfmove':hm}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'})],
 [('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'})],
 [('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'})]]
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)

prompt:
After the last right is lost, the rights field is "" instead of "-".

Input: {"board" (before the move), "rights": castling rights string or "-", "move": [from, to], "halfmove"}. Return the next {"rights", "ep", "halfmove"}: a king move removes both of its side's rights; any move from or onto h1/a1/h8/a8 removes the matching right; a pawn double step sets ep to the skipped square only when an enemy pawn stands beside the destination; the halfmove clock resets on pawn moves and captures, else increments. Empty rights render as "-".

split: open-access


broken_source:
"""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]; cap=b.get(to)
    rights=x['rights'].replace('-','')
    if p=='K': rights=rights.replace('K','').replace('Q','')
    if p=='k': rights=rights.replace('k','').replace('q','')
    for sq,r in (('h1','K'),('a1','Q'),('h8','k'),('a8','q')):
        if fr==sq or to==sq: rights=rights.replace(r,'')
    ep=None
    if abs(int(to[1])-int(fr[1]))==2:
        enemy='p' if p=='P' else 'P'
        f=ord(to[0])-97
        if any(b.get(chr(97+f+d)+to[1])==enemy for d in (-1,1)):
            ep=fr[0]+str((int(fr[1])+int(to[1]))//2)
    pawn_or_capture=p in ('P','p') or cap is not None
    hm=0 if pawn_or_capture else x['halfmove']+1
    return {'rights':rights or '-','ep':ep,'halfmove':hm}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})]]
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""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]; cap=b.get(to)
    rights=x['rights'].replace('-','')
    if p=='K': rights=rights.replace('K','').replace('Q','')
    if p=='k': rights=rights.replace('k','').replace('q','')
    for sq,r in (('h1','K'),('a1','Q'),('h8','k'),('a8','q')):
        if fr==sq or to==sq: rights=rights.replace(r,'')
    ep=None
    if p.lower()!='n' and abs(int(to[1])-int(fr[1]))==2:
        enemy='p' if p=='P' else 'P'
        f=ord(to[0])-97
        if any(b.get(chr(97+f+d)+to[1])==enemy for d in (-1,1)):
            ep=fr[0]+str((int(fr[1])+int(to[1]))//2)
    pawn_or_capture=p in ('P','p') or cap is not None
    hm=0 if pawn_or_capture else x['halfmove']+1
    return {'rights':rights or '-','ep':ep,'halfmove':hm}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})]]
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)

prompt:
Rd1-d3 next to a black pawn sets ep to d2.

Input: {"board" (before the move), "rights": castling rights string or "-", "move": [from, to], "halfmove"}. Return the next {"rights", "ep", "halfmove"}: a king move removes both of its side's rights; any move from or onto h1/a1/h8/a8 removes the matching right; a pawn double step sets ep to the skipped square only when an enemy pawn stands beside the destination; the halfmove clock resets on pawn moves and captures, else increments. Empty rights render as "-".

split: open-access


broken_source:
"""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]; cap=b.get(to)
    rights=x['rights'].replace('-','')
    if p=='K': rights=rights.replace('K','').replace('Q','')
    if p=='k': rights=rights.replace('k','').replace('q','')
    for sq,r in (('h1','K'),('a1','Q'),('h8','k'),('a8','q')):
        if fr==sq or to==sq: rights=rights.replace(r,'')
    ep=None
    if p in ('P','p') and abs(int(to[1])-int(fr[1]))==2:
        enemy='p' if p=='P' else 'P'
        f=ord(to[0])-97
        if any(b.get(chr(97+f+d)+to[1]) in ('p','P') for d in (-1,1)):
            ep=fr[0]+str((int(fr[1])+int(to[1]))//2)
    pawn_or_capture=p in ('P','p') or cap is not None
    hm=0 if pawn_or_capture else x['halfmove']+1
    return {'rights':rights or '-','ep':ep,'halfmove':hm}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'})],
 [('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'})],
 [('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'})]]
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)

source:
"""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]; cap=b.get(to)
    rights=x['rights'].replace('-','')
    if p=='K': rights=rights.replace('K','').replace('Q','')
    if p=='k': rights=rights.replace('k','').replace('q','')
    for sq,r in (('h1','K'),('a1','Q'),('h8','k'),('a8','q')):
        if fr==sq or to==sq: rights=rights.replace(r,'')
    ep=None
    if p in ('P','p') and abs(int(to[1])-int(fr[1]))==2:
        enemy='p' if p=='P' else 'P'
        f=ord(to[0])-97
        if any(b.get(chr(97+f+d)+to[1])=='p' for d in (-1,1)):
            ep=fr[0]+str((int(fr[1])+int(to[1]))//2)
    pawn_or_capture=p in ('P','p') or cap is not None
    hm=0 if pawn_or_capture else x['halfmove']+1
    return {'rights':rights or '-','ep':ep,'halfmove':hm}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'})],
 [('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', 'halfmove': 0, 'rights': '-'}),
  ('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'})],
 [('double step no enemy beside',
   {'board': {'a4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'}),
  ('knight capture resets',
   {'board': {'e1': 'K', 'e8': 'k', 'f3': 'p', 'g1': 'N'},
    'halfmove': 7,
    'move': ['g1', 'f3'],
    'rights': 'K'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'}),
  ('single pawn step',
   {'board': {'a2': 'P', 'e1': 'K', 'e8': 'k'},
    'halfmove': 11,
    'move': ['a2', 'a3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('rook two-rank move',
   {'board': {'c3': 'p', 'd1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 1,
    'move': ['d1', 'd3'],
    'rights': '-'},
   {'ep': None, 'halfmove': 2, 'rights': '-'}),
  ('queen two-rank move',
   {'board': {'c4': 'P', 'd6': 'q', 'e1': 'K', 'e8': 'k'},
    'halfmove': 6,
    'move': ['d6', 'd4'],
    'rights': 'k'},
   {'ep': None, 'halfmove': 7, 'rights': 'k'})],
 [('king move clears both',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k', 'h1': 'R'},
    'halfmove': 3,
    'move': ['e1', 'f1'],
    'rights': 'KQkq'},
   {'ep': None, 'halfmove': 4, 'rights': 'kq'}),
  ('black king move',
   {'board': {'e1': 'K', 'e8': 'k'}, 'halfmove': 0, 'move': ['e8', 'd8'], 'rights': 'KQkq'},
   {'ep': None, 'halfmove': 1, 'rights': 'KQ'}),
  ('rook captured on a8',
   {'board': {'a8': 'r', 'b7': 'B', 'e1': 'K', 'e8': 'k'},
    'halfmove': 5,
    'move': ['b7', 'a8'],
    'rights': 'Kkq'},
   {'ep': None, 'halfmove': 0, 'rights': 'Kk'}),
  ('bishop takes h8 rook',
   {'board': {'a1': 'B', 'e1': 'K', 'e8': 'k', 'h8': 'r'},
    'halfmove': 5,
    'move': ['a1', 'h8'],
    'rights': 'KQk'},
   {'ep': None, 'halfmove': 0, 'rights': 'K'}),
  ('rook leaves corner',
   {'board': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'halfmove': 9,
    'move': ['a1', 'a5'],
    'rights': 'KQ'},
   {'ep': None, 'halfmove': 10, 'rights': 'K'}),
  ('double step beside own pawn',
   {'board': {'e1': 'K', 'e2': 'P', 'e8': 'k', 'f4': 'P'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': None, 'halfmove': 0, 'rights': '-'}),
  ('black double step',
   {'board': {'b5': 'P', 'c7': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': 'c6', 'halfmove': 0, 'rights': 'kq'}),
  ('black double step beside black pawn',
   {'board': {'c7': 'p', 'd5': 'p', 'e1': 'K', 'e8': 'k'},
    'halfmove': 2,
    'move': ['c7', 'c5'],
    'rights': 'kq'},
   {'ep': None, 'halfmove': 0, 'rights': 'kq'})]]
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)

prompt:
e2-e4 next to a white pawn on f4 sets ep to e3.

Input: {"board" (before the move), "rights": castling rights string or "-", "move": [from, to], "halfmove"}. Return the next {"rights", "ep", "halfmove"}: a king move removes both of its side's rights; any move from or onto h1/a1/h8/a8 removes the matching right; a pawn double step sets ep to the skipped square only when an enemy pawn stands beside the destination; the halfmove clock resets on pawn moves and captures, else increments. Empty rights render as "-".

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    u=x['uci']; b=x['board']
    if len(u) not in (4,5): return 'syntax'
    fr,to,promo=u[:2],u[2:4],u[4:]
    for s in (fr,to):
        if s[0] not in 'abcdefgh' or not s[1].isdigit(): return 'syntax'
    if fr==to: return 'syntax'
    p=b.get(fr)
    if p is None: return 'no piece'
    last=(p=='P' and to[1]=='8') or (p=='p' and to[1]=='1')
    if last and not promo: return 'promotion required'
    if promo and not last: return 'unexpected promotion'
    if promo and promo not in 'qrbn': return 'bad promotion'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok')],
 [('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion')],
 [('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece')],
 [('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    u=x['uci']; b=x['board']
    if len(u) not in (4,5): return 'syntax'
    fr,to,promo=u[:2],u[2:4],u[4:]
    for s in (fr,to):
        if s[0] not in 'abcdefgh' or int(s[1])>8: return 'syntax'
    if fr==to: return 'syntax'
    p=b.get(fr)
    if p is None: return 'no piece'
    last=(p=='P' and to[1]=='8') or (p=='p' and to[1]=='1')
    if last and not promo: return 'promotion required'
    if promo and not last: return 'unexpected promotion'
    if promo and promo not in 'qrbn': return 'bad promotion'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok')],
 [('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion')],
 [('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece')],
 [('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')]]
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)

prompt:
"e2e9" passes syntax validation.

Input: {"board", "uci": move string}. Return "ok" or a reason: "syntax" (length not 4-5, squares outside a1-h8, or from equals to), "no piece" (origin empty), "promotion required" (a white pawn reaching rank 8 or black pawn reaching rank 1 without a suffix), "unexpected promotion" (suffix on any other move), "bad promotion" (suffix not one of q, r, b, n).

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    u=x['uci']; b=x['board']
    if len(u) not in (4,5): return 'syntax'
    fr,to,promo=u[:2],u[2:4],u[4:]
    for s in (fr,to):
        if s[0] not in 'abcdefgh' or s[1] not in '12345678': return 'syntax'
    if fr==to: return 'syntax'
    p=b.get(fr)
    if p is None: return 'no piece'
    last=(p=='P' and to[1]=='8') or (p=='p' and to[1]=='1')
    if last and not promo: return 'promotion required'
    if promo and not last: return 'unexpected promotion'
    if promo and promo not in 'qrbnk': return 'bad promotion'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion')],
 [('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion')],
 [('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece')],
 [('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    u=x['uci']; b=x['board']
    if len(u) not in (4,5): return 'syntax'
    fr,to,promo=u[:2],u[2:4],u[4:]
    for s in (fr,to):
        if s[0] not in 'abcdefgh' or s[1] not in '12345678': return 'syntax'
    if fr==to: return 'syntax'
    p=b.get(fr)
    if p is None: return 'no piece'
    last=(p=='P' and to[1]=='8') or (p=='p' and to[1]=='1')
    if last and not promo: return 'promotion required'
    if promo and not last: return 'unexpected promotion'
    if promo and promo not in 'qrbnp': return 'bad promotion'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion')],
 [('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion')],
 [('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece')],
 [('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')]]
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)

prompt:
"e7e8k" is reported ok.

Input: {"board", "uci": move string}. Return "ok" or a reason: "syntax" (length not 4-5, squares outside a1-h8, or from equals to), "no piece" (origin empty), "promotion required" (a white pawn reaching rank 8 or black pawn reaching rank 1 without a suffix), "unexpected promotion" (suffix on any other move), "bad promotion" (suffix not one of q, r, b, n).

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    u=x['uci']; b=x['board']
    if len(u) not in (4,5): return 'syntax'
    fr,to,promo=u[:2],u[2:4],u[4:]
    for s in (fr,to):
        if s[0] not in 'abcdefgh' or s[1] not in '12345678': return 'syntax'
    if fr==to: return 'syntax'
    p=b.get(fr)
    if p is None: return 'no piece'
    last=to[1] in '18'
    if last and not promo: return 'promotion required'
    if promo and not last: return 'unexpected promotion'
    if promo and promo not in 'qrbn': return 'bad promotion'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    u=x['uci']; b=x['board']
    if len(u) not in (4,5): return 'syntax'
    fr,to,promo=u[:2],u[2:4],u[4:]
    for s in (fr,to):
        if s[0] not in 'abcdefgh' or s[1] not in '12345678': return 'syntax'
    if fr==to: return 'syntax'
    p=b.get(fr)
    if p is None: return 'no piece'
    last=p=='P' and to[1]=='8'
    if last and not promo: return 'promotion required'
    if promo and not last: return 'unexpected promotion'
    if promo and promo not in 'qrbn': return 'bad promotion'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')]]
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)

prompt:
"a1a8" for a rook returns "promotion required".

Input: {"board", "uci": move string}. Return "ok" or a reason: "syntax" (length not 4-5, squares outside a1-h8, or from equals to), "no piece" (origin empty), "promotion required" (a white pawn reaching rank 8 or black pawn reaching rank 1 without a suffix), "unexpected promotion" (suffix on any other move), "bad promotion" (suffix not one of q, r, b, n).

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    u=x['uci']; b=x['board']
    if len(u) not in (4,5): return 'syntax'
    fr,to,promo=u[:2],u[2:4],u[4:]
    for s in (fr,to):
        if s[0] not in 'abcdefgh' or s[1] not in '12345678': return 'syntax'
    pass
    p=b.get(fr)
    if p is None: return 'no piece'
    last=(p=='P' and to[1]=='8') or (p=='p' and to[1]=='1')
    if last and not promo: return 'promotion required'
    if promo and not last: return 'unexpected promotion'
    if promo and promo not in 'qrbn': return 'bad promotion'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece')],
 [('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece')]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    u=x['uci']; b=x['board']
    if len(u) not in (4,5): return 'syntax'
    fr,to,promo=u[:2],u[2:4],u[4:]
    for s in (fr,to):
        if s[0] not in 'abcdefgh' or s[1] not in '12345678': return 'syntax'
    if fr[0]==to[0]: return 'syntax'
    p=b.get(fr)
    if p is None: return 'no piece'
    last=(p=='P' and to[1]=='8') or (p=='p' and to[1]=='1')
    if last and not promo: return 'promotion required'
    if promo and not last: return 'unexpected promotion'
    if promo and promo not in 'qrbn': return 'bad promotion'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('black promotes knight', {'board': {'b2': 'p'}, 'uci': 'b2a1n'}, 'ok'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('suffix on quiet move', {'board': {'g1': 'N'}, 'uci': 'g1f3q'}, 'unexpected promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('too long', {'board': {'e7': 'P'}, 'uci': 'e7e8qq'}, 'syntax'),
  ('too short', {'board': {'e2': 'P'}, 'uci': 'e2e'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('simple move', {'board': {'e2': 'P'}, 'uci': 'e2e4'}, 'ok'),
  ('white promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8q'}, 'ok'),
  ('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('castling encoding', {'board': {'e1': 'K', 'h1': 'R'}, 'uci': 'e1g1'}, 'ok')],
 [('white needs promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8'}, 'promotion required'),
  ('black needs promotion', {'board': {'b2': 'p'}, 'uci': 'b2b1'}, 'promotion required'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece')],
 [('rank nine', {'board': {'e2': 'P'}, 'uci': 'e2e9'}, 'syntax'),
  ('rank zero', {'board': {'e2': 'P'}, 'uci': 'e2e0'}, 'syntax'),
  ('rook reaches last rank', {'board': {'a1': 'R'}, 'uci': 'a1a8'}, 'ok'),
  ('king promotion', {'board': {'e7': 'P'}, 'uci': 'e7e8k'}, 'bad promotion'),
  ('pawn promotion letter', {'board': {'c7': 'P'}, 'uci': 'c7c8p'}, 'bad promotion'),
  ('null move', {'board': {'e2': 'P'}, 'uci': 'e2e2'}, 'syntax'),
  ('vertical rook move', {'board': {'h1': 'R'}, 'uci': 'h1h5'}, 'ok'),
  ('empty origin', {'board': {'e2': 'P'}, 'uci': 'd2d4'}, 'no piece')]]
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)

prompt:
"e2e2" is reported ok.

Input: {"board", "uci": move string}. Return "ok" or a reason: "syntax" (length not 4-5, squares outside a1-h8, or from equals to), "no piece" (origin empty), "promotion required" (a white pawn reaching rank 8 or black pawn reaching rank 1 without a suffix), "unexpected promotion" (suffix on any other move), "bad promotion" (suffix not one of q, r, b, n).

split: open-access