Reputation: 49
The best way I found to check if the move captured a piece is to count all the pieces before and after the move and verify if different, but seems to me very inefficient and not elegant.
Upvotes: 1
Views: 2762
Reputation: 192
Board
's is_capture
method encapsulates the necessary logic for normal captures as well as en passant:
# Position after e4 d5
b = chess.Board('rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 1')
move = chess.Move.from_uci('e4d5')
print(b.is_capture(move)) # True
Here is how they actually implement it (copied directly from Board
):
def is_capture(self, move: Move) -> bool:
"""Checks if the given pseudo-legal move is a capture."""
touched = BB_SQUARES[move.from_square] ^ BB_SQUARES[move.to_square]
return bool(touched & self.occupied_co[not self.turn]) or self.is_en_passant(move)
Upvotes: 1
Reputation: 21
You also need to check for en passant, but I think that is all you have to worry about.
The following code should work; it returns 0 if nothing captured, otherwise uses the codes from python chess (e.g. chess.PAWN, chess.ROOK, etc.):
def CapturedPiece(board, move):
if board.is_capture(move):
if board.is_en_passant(move):
return chess.PAWN
else:
return board.piece_at(move.to_square).piece_type
return 0
I couldn't find a function in the module that does this already, but that doesn't mean it doesn't exist or that it won't be added at some point.
Upvotes: 2
Reputation: 49
I've found a better way than counting (even if still not nice is the best so far).
Verify if in the target square there is a piece or if the move is of a pawn verify if source and target file (x coordinate) is different.
quiet = board.piece_type_at(move.to_square)==None
if ( board.piece_type_at(move.from_square)==chess.PAWN ) \
and ( chess.square_file(move.from_square)!=chess.square_file(move.to_square) ):
quiet=False
Upvotes: 0