Spaces:
Sleeping
Sleeping
| # chess_engine/pieces.py | |
| import chess | |
| from typing import Dict, List, Optional, Tuple | |
| from enum import Enum | |
| class PieceType(Enum): | |
| PAWN = chess.PAWN | |
| KNIGHT = chess.KNIGHT | |
| BISHOP = chess.BISHOP | |
| ROOK = chess.ROOK | |
| QUEEN = chess.QUEEN | |
| KING = chess.KING | |
| class PieceColor(Enum): | |
| WHITE = chess.WHITE | |
| BLACK = chess.BLACK | |
| class ChessPiece: | |
| """Represents a chess piece with its properties and behaviors""" | |
| # Unicode symbols for pieces | |
| UNICODE_PIECES = { | |
| chess.WHITE: { | |
| chess.PAWN: "♙", chess.KNIGHT: "♘", chess.BISHOP: "♗", | |
| chess.ROOK: "♖", chess.QUEEN: "♕", chess.KING: "♔" | |
| }, | |
| chess.BLACK: { | |
| chess.PAWN: "♟", chess.KNIGHT: "♞", chess.BISHOP: "♝", | |
| chess.ROOK: "♜", chess.QUEEN: "♛", chess.KING: "♚" | |
| } | |
| } | |
| # Piece values for evaluation | |
| PIECE_VALUES = { | |
| chess.PAWN: 1, | |
| chess.KNIGHT: 3, | |
| chess.BISHOP: 3, | |
| chess.ROOK: 5, | |
| chess.QUEEN: 9, | |
| chess.KING: 0 # King is invaluable | |
| } | |
| def __init__(self, piece_type: chess.PieceType, color: chess.Color): | |
| self.piece_type = piece_type | |
| self.color = color | |
| self.piece = chess.Piece(piece_type, color) | |
| def symbol(self) -> str: | |
| """Get the piece symbol (uppercase for white, lowercase for black)""" | |
| return self.piece.symbol() | |
| def unicode_symbol(self) -> str: | |
| """Get the Unicode symbol for the piece""" | |
| return self.UNICODE_PIECES[self.color][self.piece_type] | |
| def value(self) -> int: | |
| """Get the piece value""" | |
| return self.PIECE_VALUES[self.piece_type] | |
| def name(self) -> str: | |
| """Get the piece name""" | |
| piece_names = { | |
| chess.PAWN: "Pawn", | |
| chess.KNIGHT: "Knight", | |
| chess.BISHOP: "Bishop", | |
| chess.ROOK: "Rook", | |
| chess.QUEEN: "Queen", | |
| chess.KING: "King" | |
| } | |
| return piece_names[self.piece_type] | |
| def color_name(self) -> str: | |
| """Get the color name""" | |
| return "White" if self.color == chess.WHITE else "Black" | |
| def __str__(self) -> str: | |
| return f"{self.color_name} {self.name}" | |
| def __repr__(self) -> str: | |
| return f"ChessPiece({self.piece_type}, {self.color})" | |
| class PieceManager: | |
| """Manages piece-related operations and utilities""" | |
| def create_piece(piece_type: str, color: str) -> Optional[ChessPiece]: | |
| """ | |
| Create a piece from string representations | |
| Args: | |
| piece_type: 'pawn', 'knight', 'bishop', 'rook', 'queen', 'king' | |
| color: 'white' or 'black' | |
| Returns: | |
| ChessPiece instance or None if invalid input | |
| """ | |
| piece_type_map = { | |
| 'pawn': chess.PAWN, | |
| 'knight': chess.KNIGHT, | |
| 'bishop': chess.BISHOP, | |
| 'rook': chess.ROOK, | |
| 'queen': chess.QUEEN, | |
| 'king': chess.KING | |
| } | |
| color_map = { | |
| 'white': chess.WHITE, | |
| 'black': chess.BLACK | |
| } | |
| if piece_type.lower() not in piece_type_map or color.lower() not in color_map: | |
| return None | |
| return ChessPiece( | |
| piece_type_map[piece_type.lower()], | |
| color_map[color.lower()] | |
| ) | |
| def get_piece_moves(board: chess.Board, square: str) -> List[str]: | |
| """ | |
| Get all possible moves for a piece at given square | |
| Args: | |
| board: Chess board instance | |
| square: Square in algebraic notation | |
| Returns: | |
| List of destination squares in algebraic notation | |
| """ | |
| try: | |
| square_index = chess.parse_square(square) | |
| piece = board.piece_at(square_index) | |
| if piece is None: | |
| return [] | |
| moves = [] | |
| for move in board.legal_moves: | |
| if move.from_square == square_index: | |
| moves.append(chess.square_name(move.to_square)) | |
| return moves | |
| except ValueError: | |
| return [] | |
| def get_piece_attacks(board: chess.Board, square: str) -> List[str]: | |
| """ | |
| Get all squares attacked by piece at given square | |
| Args: | |
| board: Chess board instance | |
| square: Square in algebraic notation | |
| Returns: | |
| List of attacked squares in algebraic notation | |
| """ | |
| try: | |
| square_index = chess.parse_square(square) | |
| piece = board.piece_at(square_index) | |
| if piece is None: | |
| return [] | |
| attacks = [] | |
| for target_square in chess.SQUARES: | |
| if board.is_attacked_by(piece.color, target_square): | |
| # Check if this specific piece is doing the attacking | |
| # This is a simplified check - in a real game you might need more sophisticated logic | |
| attacks.append(chess.square_name(target_square)) | |
| return attacks | |
| except ValueError: | |
| return [] | |
| def get_material_count(board: chess.Board) -> Dict[str, Dict[str, int]]: | |
| """ | |
| Get material count for both sides | |
| Args: | |
| board: Chess board instance | |
| Returns: | |
| Dictionary with material counts for white and black | |
| """ | |
| white_pieces = {'pawn': 0, 'knight': 0, 'bishop': 0, 'rook': 0, 'queen': 0, 'king': 0} | |
| black_pieces = {'pawn': 0, 'knight': 0, 'bishop': 0, 'rook': 0, 'queen': 0, 'king': 0} | |
| piece_names = { | |
| chess.PAWN: 'pawn', | |
| chess.KNIGHT: 'knight', | |
| chess.BISHOP: 'bishop', | |
| chess.ROOK: 'rook', | |
| chess.QUEEN: 'queen', | |
| chess.KING: 'king' | |
| } | |
| for square in chess.SQUARES: | |
| piece = board.piece_at(square) | |
| if piece: | |
| piece_name = piece_names[piece.piece_type] | |
| if piece.color == chess.WHITE: | |
| white_pieces[piece_name] += 1 | |
| else: | |
| black_pieces[piece_name] += 1 | |
| return { | |
| 'white': white_pieces, | |
| 'black': black_pieces | |
| } | |
| def get_material_value(board: chess.Board) -> Dict[str, int]: | |
| """ | |
| Get total material value for both sides | |
| Args: | |
| board: Chess board instance | |
| Returns: | |
| Dictionary with material values for white and black | |
| """ | |
| white_value = 0 | |
| black_value = 0 | |
| for square in chess.SQUARES: | |
| piece = board.piece_at(square) | |
| if piece: | |
| value = ChessPiece.PIECE_VALUES[piece.piece_type] | |
| if piece.color == chess.WHITE: | |
| white_value += value | |
| else: | |
| black_value += value | |
| return { | |
| 'white': white_value, | |
| 'black': black_value, | |
| 'advantage': white_value - black_value | |
| } | |
| def get_piece_list(board: chess.Board) -> Dict[str, List[Dict[str, str]]]: | |
| """ | |
| Get list of all pieces on the board | |
| Args: | |
| board: Chess board instance | |
| Returns: | |
| Dictionary with lists of white and black pieces | |
| """ | |
| white_pieces = [] | |
| black_pieces = [] | |
| for square in chess.SQUARES: | |
| piece = board.piece_at(square) | |
| if piece: | |
| piece_info = { | |
| 'type': chess.piece_name(piece.piece_type), | |
| 'square': chess.square_name(square), | |
| 'symbol': piece.symbol(), | |
| 'unicode': ChessPiece.UNICODE_PIECES[piece.color][piece.piece_type] | |
| } | |
| if piece.color == chess.WHITE: | |
| white_pieces.append(piece_info) | |
| else: | |
| black_pieces.append(piece_info) | |
| return { | |
| 'white': white_pieces, | |
| 'black': black_pieces | |
| } | |
| def is_promotion_move(board: chess.Board, move_str: str) -> bool: | |
| """ | |
| Check if a move is a pawn promotion | |
| Args: | |
| board: Chess board instance | |
| move_str: Move in UCI notation | |
| Returns: | |
| True if the move is a promotion | |
| """ | |
| try: | |
| move = chess.Move.from_uci(move_str) | |
| return move.promotion is not None | |
| except ValueError: | |
| return False | |
| def get_promotion_pieces() -> List[Dict[str, str]]: | |
| """ | |
| Get available promotion pieces | |
| Returns: | |
| List of promotion piece options | |
| """ | |
| return [ | |
| {'type': 'queen', 'symbol': 'Q', 'name': 'Queen'}, | |
| {'type': 'rook', 'symbol': 'R', 'name': 'Rook'}, | |
| {'type': 'bishop', 'symbol': 'B', 'name': 'Bishop'}, | |
| {'type': 'knight', 'symbol': 'N', 'name': 'Knight'} | |
| ] |