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