TDT4109/Exercise 10/chess/piece.py

75 lines
2.4 KiB
Python

from typing import Iterable, Callable
from itertools import product
class Piece:
def __init__(self, type, color):
self.type = type
self.color = color
def __str__(self):
return self.type.upper() if self.color == 'white' else self.type
@staticmethod
def possibleMoves(x, y, board) -> Callable[[int, int], Iterable[tuple]]:
piece = board.getPieceAt(x, y)
moves = []
pieceIsEnemyColor = lambda pieceToCheck: pieceToCheck != None and pieceToCheck.color != piece.color
pieceIsEmpty = lambda pieceToCheck: pieceToCheck == None
pieceIsEmptyOrEnemyColor = lambda pieceToCheck: pieceToCheck == None or pieceToCheck.color != piece.color
def addMoveIfTrue(xOffset, yOffset, condition):
if condition(board.getPieceAt(x + xOffset, y + yOffset)):
moves.append((x + xOffset, y + yOffset))
return True
return False
def addWhileInsideBoard(direction):
localX = x
localY = y
while localX not in [0, 7] and localY not in [0, 7]:
localX += direction[0]
localY += direction[1]
if board.getPieceAt(localX, localY) == None:
moves.append((localX, localY))
else:
if board.getPieceAt(localX, localY).color != piece.color:
moves.append((localX, localY))
return
if piece.type == 'p':
addMoveIfTrue(1, 1, pieceIsEnemyColor)
addMoveIfTrue(-1, 1, pieceIsEnemyColor)
if addMoveIfTrue(0, 1, pieceIsEmpty):
addMoveIfTrue(0, 2, lambda pieceToCheck: pieceToCheck == None and piece.moves == 0)
elif piece.type == 'n':
positions = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)]
for position in positions:
addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor)
elif piece.type == 'k':
positions = list(product([-1, 0, 1], repeat=2))
positions.remove((0, 0))
for position in positions:
addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor)
# TODO: Check moves for check and remove the bad ones
elif piece.type == 'r':
for direction in product([0, 1], repeat=2):
addWhileInsideBoard(direction)
elif piece.type == 'b':
for direction in product([-1, 1], repeat=2):
addWhileInsideBoard(direction)
elif piece.type == 'q':
directions = list(product([-1, 0, 1], repeat=2))
directions.remove((0, 0))
for direction in directions:
addWhileInsideBoard(direction)
return moves