diff --git a/src/logic/board.py b/src/logic/board.py index 105c8ca..504da95 100644 --- a/src/logic/board.py +++ b/src/logic/board.py @@ -172,9 +172,6 @@ class Board: piece = move.piece - # -- Set en passant target if needed - ret._en_passant_target = self._en_passant_target - # -- Actually make the move pieces_moving, other_pieces = (ret._white, ret._black) if piece.colour == Colour.WHITE else (ret._black, ret._white) @@ -183,6 +180,16 @@ class Board: if move.pos in other_pieces: del other_pieces[move.pos] + if move.en_passant: + pos_to_remove = Position(move.pos.x, move.pos.y + (1 if self._turn == Colour.BLACK else -1)) + del other_pieces[pos_to_remove] + + # -- Set en passant target if needed + if move.becomes_en_passant_target: + ret._en_passant_target = pieces_moving[move.pos] + else: + ret._en_passant_target = None + # -- Handle castling (just move the rook over) if move.castle_side == CastleSide.King: rook_pos = Position(7, piece.pos.y) diff --git a/src/logic/move.py b/src/logic/move.py index f54034c..0336e55 100644 --- a/src/logic/move.py +++ b/src/logic/move.py @@ -8,11 +8,13 @@ class CastleSide(Enum): Queen = "O-O-O" class Move: - def __init__(self, piece: "Piece", pos: Position,/, is_capturing: bool = False, castle_side: CastleSide = CastleSide.Neither) -> None: + def __init__(self, piece: "Piece", pos: Position,/, is_capturing: bool = False, castle_side: CastleSide = CastleSide.Neither, en_passant: bool = False, becomes_en_passant_target: bool = False) -> None: self.piece = piece self.pos = pos self.is_capturing = is_capturing self.castle_side = castle_side + self.becomes_en_passant_target = becomes_en_passant_target + self.en_passant = en_passant def to_algebraic(self) -> str: raise NotImplementedError("The move can't be translated to algbraic notation, as it was not implemented") diff --git a/src/logic/pieces/pawn.py b/src/logic/pieces/pawn.py index c9dccf3..a01abda 100644 --- a/src/logic/pieces/pawn.py +++ b/src/logic/pieces/pawn.py @@ -24,18 +24,30 @@ class Pawn(Piece): if capturable_piece.colour != self.colour: ret.append(Move(self, capturable_piece.pos, is_capturing = True)) + # -- Can we capture en passant? + if board._en_passant_target is not None and \ + board._en_passant_target.pos.y == self.pos.y and ( + board._en_passant_target.pos.x == self.pos.x - 1 + or board._en_passant_target.pos.x == self.pos.x + 1 + ): + if board._en_passant_target.colour != self.colour: + old_pos = board._en_passant_target.pos + new_pos = Position(old_pos.x, old_pos.y + (1 if self.colour == Colour.WHITE else -1)) + ret.append(Move(self, new_pos, is_capturing = True, en_passant = True)) + + # -- Normal moves if self.colour == Colour.WHITE: for dy in range(1, 3 if self.pos.y == 1 else 2): if self.pos.y + dy > 7 or board.piece_at(self.pos.x, self.pos.y + dy): break pos = Position(self.pos.x, self.pos.y + dy) - ret.append(Move(self, pos)) + ret.append(Move(self, pos, becomes_en_passant_target=dy==2)) else: for dy in range(1, 3 if self.pos.y == 6 else 2): if self.pos.y - dy < 0 or board.piece_at(self.pos.x, self.pos.y - dy): break pos = Position(self.pos.x, self.pos.y - dy) - ret.append(Move(self, pos)) + ret.append(Move(self, pos, becomes_en_passant_target=dy==2)) if not looking_for_check and board.is_check_for(self.colour): return self.keep_only_blocking(ret, board)