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

En Passant Capture Not in board.legal_moves although it is. #14

Closed johnmapesjr closed 9 years ago

johnmapesjr commented 9 years ago

!/usr/bin/python3

import chess

b = chess.Bitboard('rnk2bnr/8/b4p2/p1p2Pp1/P1P5/7p/3N3P/R1BK1B1R w - g6 0 27') print(list(b.legal_moves)) print(chess.Move.from_uci('f5g6') in b.legal_moves) print(chess.Move.from_uci('d2b1') in b.legal_moves)

niklasf commented 9 years ago

Thanks for reporting this.

I think it has been fixed in 4d8bb839fd21057d7da539c35a7b050bc43840cc (and the fix released in 0.4.2).

I can not reproduce it in the latest version. Which version are you using?

johnmapesjr commented 9 years ago

We are using version 4.1

Is there any way to tell Black, White or Draw when board.is_game_over() evaluates to True?

Thanks, John

On Sat, Nov 8, 2014 at 4:22 AM, Niklas Fiekas notifications@github.com wrote:

Thanks for reporting this.

I think this has been fixed in 4d8bb83 https://github.com/niklasf/python-chess/commit/4d8bb839fd21057d7da539c35a7b050bc43840cc (and the fix released in 0.5.0).

I can not reproduce it in the latest version. Which version are you using?

— Reply to this email directly or view it on GitHub https://github.com/niklasf/python-chess/issues/14#issuecomment-62252867.

niklasf commented 9 years ago

Please update to the latest version in order to fix this bug (and a few other known ones).

The most efficient code would be:

if board.is_seventyfive_moves() or board.is_fivefold_repitition():
    result = "1/2-1/2"
else if not board.legal_moves:
    if board.is_check():
        result = "1-0" if board.turn == chess.BLACK else "0-1" # Checkmate
    else:
        result = "1/2-1/2" # Stalemate
else:
    result = "*"

Note that board.is_game_over() does not take into account draws that need to be claimed by one side.

If you change the first line of the sample code to

if board.can_claim_draw():

that would work.

Of course a game still could end by resignation or an agreed draw.

So far I've been hesistant to add something like board.result() because of things like these.

Best regards Niklas