niklasf / python-chess

A chess library for Python, with move generation and validation, PGN parsing and writing, Polyglot opening book reading, Gaviota tablebase probing, Syzygy tablebase probing, and UCI/XBoard engine communication
https://python-chess.readthedocs.io/en/latest/
GNU General Public License v3.0
2.45k stars 531 forks source link

Illegal san, but legal uci move leading to two black kings? #1079

Closed LilacPeregrine closed 6 months ago

LilacPeregrine commented 6 months ago

I have the position "2k5/pp2n2Q/8/P2p4/8/P1p2q2/2P2P1P/5RK1 b - - 4 23" it is black to move.

When i tell it ( board.push_san("Kh1") ), it errors (as expected), as black cannot move the white king. But when I do this:

import chess board = chess.Board("2k5/pp2n2Q/8/P2p4/8/P1p2q2/2P2P1P/5RK1 b - - 4 23") v = chess.Move.from_uci('g1h1') board.push(v) print(board)

It works without error, and it turns the white king into the black king in the process. is this a result of intended behavior, or a bug?

niklasf commented 6 months ago

The safe equivalent to board.push_san() would be board.push_uci(), which are documented to raise exceptions.

Separately constructing a move object and using board.push() has the following precondition:

:warning: Moves are not checked for legality. It is the caller’s responsibility to ensure that the move is at least pseudo-legal or a null move.

It's violated here, so strange things are allowed to happen. It's unfortunate, but not asserting legality in this case is an important performance tradeoff.