81 lines
3.8 KiB
Python
81 lines
3.8 KiB
Python
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.queen import Queen
|
|
from logic.pieces.rook import Rook
|
|
from logic.position import Position
|
|
|
|
class Pawn(Piece):
|
|
def legal_moves(self, board, / , looking_for_check = False) -> list[Move]:
|
|
ret = []
|
|
|
|
# can we capture to the left?
|
|
if self.pos.x > 0 and (
|
|
(self.colour == Colour.WHITE and (capturable_piece := board.piece_at(self.pos.x - 1, self.pos.y + 1)))
|
|
or
|
|
(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 (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?
|
|
if self.pos.x < 7 and (
|
|
(self.colour == Colour.WHITE and (capturable_piece := board.piece_at(self.pos.x + 1, self.pos.y + 1)))
|
|
or
|
|
(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 (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?
|
|
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):
|
|
y = self.pos.y + dy
|
|
if y > 7 or board.piece_at(self.pos.x, y):
|
|
break
|
|
pos = Position(self.pos.x, y)
|
|
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:
|
|
for dy in range(1, 3 if self.pos.y == 6 else 2):
|
|
y = self.pos.y - dy
|
|
if y < 0 or board.piece_at(self.pos.x, y):
|
|
break
|
|
pos = Position(self.pos.x, y)
|
|
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):
|
|
return self.keep_only_blocking(ret, board)
|
|
|
|
return ret
|
|
|
|
def letter(self):
|
|
return "p"
|