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

N = 1
observations = []
def solve(x):
    parts=x.split()
    if len(parts)!=6: return 'invalid'
    rows=parts[0].split('/')
    if len(rows)!=8: return 'invalid'
    board={}
    for i,row in enumerate(rows):
        rank=8-i; f=0
        for ch in row:
            if ch.isdigit(): f+=int(ch)
            elif ch in 'pnbrqkPNBRQK':
                if f>7: return 'invalid'
                board[chr(97+f)+str(rank)]=ch; f+=1
            else: return 'invalid'
        if f!=8: return 'invalid'
    vals=list(board.values())
    if 'K' not in vals or 'k' not in vals: return 'invalid'
    turn=parts[1]
    if turn not in ('w','b'): return 'invalid'
    cast='' if parts[2]=='-' else parts[2]
    if any(c not in 'KQkq' for c in cast): return 'invalid'
    ep=None if parts[3]=='-' else parts[3]
    if ep is not None and ep[1:]!=('6' if turn=='w' else '3'): return 'invalid'
    if not (parts[4].isdigit() and parts[5].isdigit()) or int(parts[5])<1: return 'invalid'
    return {'pieces':board,'turn':turn,'castling':cast,'ep':ep,'halfmove':int(parts[4]),'fullmove':int(parts[5])}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid')],
 [('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid')],
 [('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid'),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'}),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'}),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid'),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid'),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')]]
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):
    parts=x.split()
    if len(parts)!=6: return 'invalid'
    rows=parts[0].split('/')
    if len(rows)!=8: return 'invalid'
    board={}
    for i,row in enumerate(rows):
        rank=8-i; f=0
        for ch in row:
            if ch.isdigit(): f+=int(ch)
            elif ch in 'pnbrqkPNBRQK':
                if f>7: return 'invalid'
                board[chr(97+f)+str(rank)]=ch; f+=1
            else: return 'invalid'
        if f!=8: return 'invalid'
    vals=list(board.values())
    if vals.count('K')+vals.count('k')!=2: return 'invalid'
    turn=parts[1]
    if turn not in ('w','b'): return 'invalid'
    cast='' if parts[2]=='-' else parts[2]
    if any(c not in 'KQkq' for c in cast): return 'invalid'
    ep=None if parts[3]=='-' else parts[3]
    if ep is not None and ep[1:]!=('6' if turn=='w' else '3'): return 'invalid'
    if not (parts[4].isdigit() and parts[5].isdigit()) or int(parts[5])<1: return 'invalid'
    return {'pieces':board,'turn':turn,'castling':cast,'ep':ep,'halfmove':int(parts[4]),'fullmove':int(parts[5])}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid')],
 [('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid')],
 [('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid'),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'}),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'}),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid'),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid'),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')]]
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:
A FEN with two white kings parses successfully.

Input: a FEN string. Return {"pieces": {square: piece}, "turn", "castling", "ep", "halfmove", "fullmove"} or "invalid". Placement lists rank 8 first; digits skip empty squares; each rank must total 8; exactly one king per side. Turn is w or b; castling is "-" or letters from KQkq (returned as "" when "-"); ep is "-" (null) or a square on rank 6 when white is to move, rank 3 when black is; halfmove is a non-negative integer and fullmove at least 1.

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','')
    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 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': '-'}),
  ('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': '-'})],
 [('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': '-'}),
  ('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'})],
 [('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',
   {'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'}),
  ('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'}),
  ('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'}),
  ('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'})]]
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 in 'Kk': 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 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': '-'}),
  ('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': '-'})],
 [('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': '-'}),
  ('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'})],
 [('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',
   {'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'}),
  ('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'}),
  ('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'}),
  ('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'})]]
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 Ke1-f1, white still holds the Q castling right.

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: 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 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': '-'}),
  ('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': '-'})],
 [('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 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'})],
 [('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'}),
  ('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'}),
  ('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'})],
 [('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': '-'}),
  ('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': '-'})]]
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 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 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': '-'}),
  ('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': '-'})],
 [('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 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'})],
 [('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'}),
  ('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'}),
  ('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'})],
 [('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': '-'}),
  ('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': '-'})]]
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 Bxh8, black still holds the k right.

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])==enemy for d in (-1,1)):
            ep=fr[0]+to[1]
    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': '-'}),
  ('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 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 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': '-'}),
  ('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 with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', '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'}),
  ('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'}),
  ('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': '-'}),
  ('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'}),
  ('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)

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]+fr[1]
    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': '-'}),
  ('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 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 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': '-'}),
  ('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 with adjacent enemy',
   {'board': {'d4': 'p', 'e1': 'K', 'e2': 'P', 'e8': 'k'},
    'halfmove': 4,
    'move': ['e2', 'e4'],
    'rights': '-'},
   {'ep': 'e3', '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'}),
  ('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'}),
  ('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': '-'}),
  ('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'}),
  ('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:
After e2-e4 the ep square is reported as e4 instead of 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):
    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')
    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': '-'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'})],
 [('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 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': '-'}),
  ('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'}),
  ('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'})],
 [('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 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'}),
  ('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'})],
 [('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 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'}),
  ('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': '-'})],
 [('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'}),
  ('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'}),
  ('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': '-'})]]
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=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': '-'}),
  ('quiet knight move',
   {'board': {'e1': 'K', 'e8': 'k', 'g1': 'N'}, 'halfmove': 7, 'move': ['g1', 'f3'], 'rights': 'K'},
   {'ep': None, 'halfmove': 8, 'rights': 'K'})],
 [('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 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': '-'}),
  ('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'}),
  ('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'})],
 [('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 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'}),
  ('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'})],
 [('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 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'}),
  ('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': '-'})],
 [('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'}),
  ('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'}),
  ('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': '-'})]]
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:
A knight capture increments the halfmove clock.

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