Skip to content

claim-ahead rejects valid moves that deliver checkmate (or stalemate) #1188

@dlbbld

Description

@dlbbld

I'd like to flag a corner of Board.can_claim_fifty_moves(). The predicate answers the existence question — is there at least one legal move that would satisfy a 50-move draw claim? — and accepts non-pawn, non-capture moves that complete the 50 moves, except when such a move would itself deliver checkmate or stalemate, in which case it rejects them. FIDE 9.3 does not require the announced claim move to be a non-checkmate / non-stalemate move; only that it is neither a pawn move nor a capture and that it completes the 50 moves without progress.

The procedural framing makes the distinction sharp:

  • When checkmate or stalemate is already on the board, the game has ended and the draw-claim procedure cannot be initiated. The answer "no" is correct.
  • In the claim-ahead case the procedure can be initiated: the player announces the move (the move is not yet played) and claims the draw on that announcement. A move that would deliver checkmate or stalemate when played is still a valid announced move under FIDE 9.3, provided it is non-pawn, non-capture, and completes the 50 halfmoves.

Because can_claim_fifty_moves() answers at the position level (it doesn't take a candidate move), the disagreement only surfaces in the special positions where the only non-zeroing legal move ends the game — vanishingly rare in practice. But the predicate's answer at those positions is, I think, not quite right.

Reproducer

import chess

board = chess.Board("6rk/6pp/7N/5p2/6p1/8/2q5/K7 w - - 99 60")
print(board.can_claim_fifty_moves())   # False -- per FIDE 9.3, should be True

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions