added pawn promotion

This commit is contained in:
Karma Riuk 2025-02-01 16:43:02 +01:00
parent c7884e227b
commit 92e1ff26fc
3 changed files with 37 additions and 9 deletions

View File

@ -184,6 +184,10 @@ class Board:
pos_to_remove = Position(move.pos.x, move.pos.y + (1 if self._turn == Colour.BLACK else -1)) pos_to_remove = Position(move.pos.x, move.pos.y + (1 if self._turn == Colour.BLACK else -1))
del other_pieces[pos_to_remove] del other_pieces[pos_to_remove]
if move.promotes_to is not None:
assert type(piece) == Pawn, "Trying to promote something that is not a pawn: not good!"
pieces_moving[move.pos] = move.promotes_to(move.pos, piece.colour)
# -- Set en passant target if needed # -- Set en passant target if needed
if move.becomes_en_passant_target: if move.becomes_en_passant_target:
ret._en_passant_target = pieces_moving[move.pos] ret._en_passant_target = pieces_moving[move.pos]

View File

@ -1,4 +1,5 @@
# from logic.pieces.piece import Piece # from logic.pieces.piece import Piece
from typing import Type
from logic.position import Position from logic.position import Position
from enum import Enum from enum import Enum
@ -8,13 +9,14 @@ class CastleSide(Enum):
Queen = "O-O-O" Queen = "O-O-O"
class Move: class Move:
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: 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, promotes_to: Type["Piece"] = None) -> None:
self.piece = piece self.piece = piece
self.pos = pos self.pos = pos
self.is_capturing = is_capturing self.is_capturing = is_capturing
self.castle_side = castle_side self.castle_side = castle_side
self.becomes_en_passant_target = becomes_en_passant_target self.becomes_en_passant_target = becomes_en_passant_target
self.en_passant = en_passant self.en_passant = en_passant
self.promotes_to = promotes_to
def to_algebraic(self) -> str: def to_algebraic(self) -> str:
raise NotImplementedError("The move can't be translated to algbraic notation, as it was not implemented") raise NotImplementedError("The move can't be translated to algbraic notation, as it was not implemented")

View File

@ -1,5 +1,9 @@
from logic.move import Move from logic.move import Move
from logic.pieces.bishop import Bishop
from logic.pieces.knight import Knight
from logic.pieces.piece import Colour, Piece from logic.pieces.piece import Colour, Piece
from logic.pieces.queen import Queen
from logic.pieces.rook import Rook
from logic.position import Position from logic.position import Position
class Pawn(Piece): class Pawn(Piece):
@ -13,7 +17,11 @@ class Pawn(Piece):
(self.colour == Colour.BLACK and (capturable_piece := board.piece_at(self.pos.x - 1, self.pos.y - 1))) (self.colour == Colour.BLACK and (capturable_piece := board.piece_at(self.pos.x - 1, self.pos.y - 1)))
): ):
if capturable_piece.colour != self.colour: if capturable_piece.colour != self.colour:
ret.append(Move(self, capturable_piece.pos, is_capturing = True)) if (self.colour == Colour.WHITE and capturable_piece.pos.y == 7) or (self.colour == Colour.BLACK and capturable_piece.pos.y == 0):
for piece in [Queen, Knight, Bishop, Rook]:
ret.append(Move(self, capturable_piece.pos, is_capturing=True, promotes_to=piece))
else:
ret.append(Move(self, capturable_piece.pos, is_capturing = True))
# can we capture to the right? # can we capture to the right?
if self.pos.x < 7 and ( if self.pos.x < 7 and (
@ -22,7 +30,11 @@ class Pawn(Piece):
(self.colour == Colour.BLACK and (capturable_piece := board.piece_at(self.pos.x + 1, self.pos.y - 1))) (self.colour == Colour.BLACK and (capturable_piece := board.piece_at(self.pos.x + 1, self.pos.y - 1)))
): ):
if capturable_piece.colour != self.colour: if capturable_piece.colour != self.colour:
ret.append(Move(self, capturable_piece.pos, is_capturing = True)) if (self.colour == Colour.WHITE and capturable_piece.pos.y == 7) or (self.colour == Colour.BLACK and capturable_piece.pos.y == 0):
for piece in [Queen, Knight, Bishop, Rook]:
ret.append(Move(self, capturable_piece.pos, is_capturing=True, promotes_to=piece))
else:
ret.append(Move(self, capturable_piece.pos, is_capturing = True))
# -- Can we capture en passant? # -- Can we capture en passant?
if board._en_passant_target is not None and \ if board._en_passant_target is not None and \
@ -38,16 +50,26 @@ class Pawn(Piece):
# -- Normal moves # -- Normal moves
if self.colour == Colour.WHITE: if self.colour == Colour.WHITE:
for dy in range(1, 3 if self.pos.y == 1 else 2): 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): y = self.pos.y + dy
if y > 7 or board.piece_at(self.pos.x, y):
break break
pos = Position(self.pos.x, self.pos.y + dy) pos = Position(self.pos.x, y)
ret.append(Move(self, pos, becomes_en_passant_target=dy==2)) if y == 7:
for piece in [Queen, Knight, Bishop, Rook]:
ret.append(Move(self, pos, promotes_to=piece))
else:
ret.append(Move(self, pos, becomes_en_passant_target=dy==2))
else: else:
for dy in range(1, 3 if self.pos.y == 6 else 2): 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): y = self.pos.y - dy
if y < 0 or board.piece_at(self.pos.x, y):
break break
pos = Position(self.pos.x, self.pos.y - dy) pos = Position(self.pos.x, y)
ret.append(Move(self, pos, becomes_en_passant_target=dy==2)) if y == 0:
for piece in [Queen, Knight, Bishop, Rook]:
ret.append(Move(self, pos, promotes_to=piece))
else:
ret.append(Move(self, pos, becomes_en_passant_target=dy==2))
if not looking_for_check and board.is_check_for(self.colour): if not looking_for_check and board.is_check_for(self.colour):
return self.keep_only_blocking(ret, board) return self.keep_only_blocking(ret, board)