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.4k stars 521 forks source link

Illegal move not detected as such #870

Closed Ronnypetson closed 2 years ago

Ronnypetson commented 2 years ago

Hello,

I was checking some synthetic PGN sequences generated from language models when I found out that

  1. e4 c5 2. c4 e6 3. Nf3 d5 4. e5 Nc6 5. d4 Nh6 6. Nbd2 Nf5 7. Bd3 Be7 8. O-O O-O 9. b3 Na5 10. Bb2 b6 11. a3 Bb7 12. Qe2 Rc8 13. Bb1 c4 14. Bc2 b5 15. Bd3 a6 16. Bb1 g6 17. Bd3 Nc6 18. Bb1 Na5 19. Bc2 Qd7 20. Bd3 Nac6 21. Bb1 Na5 22. Bc2 Nac6 23. Bd3 Na5 24. Bb1 Nac6 25. Bd3 Na5 26. Bb1 Nac6 27. Bd3 Na5 28. Bb1 Nac6 29. Bd3 Na5 30. Bb1 Nac6 31. Bc2 Na5 32. Bb1 1/2-1/2

should not be allowed at move 13. ... c4 (I checked by loading the PGN on chess.com), but python-chess allows such move.

Ronnypetson commented 2 years ago

Here is a print up to move 13. Bb1 image We can see clearly that c4 is not possible.

Doing

game_str = '1. e4 c5 2. c4 e6 3. Nf3 d5 4. e5 Nc6 5. d4 Nh6 6. Nbd2 Nf5 7. Bd3 Be7 8. O-O O-O 9. b3 Na5 10. Bb2 b6 11. a3 Bb7 12. Qe2 Rc8 13. Bb1 c4   1/2-1/2'

pgn = io.StringIO(game_str)
game = chess.pgn.read_game(pgn)
board = game.board()

for idx, move in enumerate(game.mainline_moves()):
  board.push(move)

Yields the final board position

image

Ronnypetson commented 2 years ago

Here is a sequence with the same problem

  1. c4 c5 2. e4 d6 3. g3 e5 4. d3 Nc6 5. Bg2 Nf6 6. Nge2 Nd4 7. O-O a6 8. Na3 Be6 9. Nc2 Be7 10. Ne3 O-O 11. Nd5 Ne8 12. Bd2 Nf6 13. Bc3 Bd7 14. Bd2 Rc8 15. b3 b5 16. Ne3 g6 17. Nd5 Ne8 18. Ne3 Nc7 19. Nd5 Ne8 20. Ne3 Nc7 21. Nd5 Be6 22. Ne3 f5 23. f4 e4
niklasf commented 2 years ago

Thanks for reporting. It "works" because c4 is interpreted as "pawn move to c4", which has a unique matching move dxc4, so that one is selected. I agree that it should probably be rejected, instead.