from typing import Optional import chess WHITE_PIECE_COLOR = "\033[97m" # Bright white BLACK_PIECE_COLOR = "\033[90m" # Bright black (gray) LIGHT_SQUARE_BG = "\033[50m" # White background DARK_SQUARE_BG = "\033[47m" # Standard blue background (darker/more blue) RESET = "\033[0m" UNICODE_PIECES = { "P": "♙", "N": "♘", "B": "♗", "R": "♖", "Q": "♕", "K": "♔", "p": "♟", "n": "♞", "b": "♝", "r": "♜", "q": "♛", "k": "♚", } def colored_unicode_board(fen: Optional[str] = None) -> str: if fen is None: fen = chess.STARTING_FEN board = chess.Board(fen) board_str = "" white_to_move = board.turn # Decide ranks and files order depending on who's to move if white_to_move: ranks = range(8, 0, -1) # 8 to 1 files = range(1, 9) # a to h else: ranks = range(1, 9) # 1 to 8 files = range(8, 0, -1) # h to a (reverse files) for rank in ranks: board_str += f"{rank} " for file in files: square = chess.square(file - 1, rank - 1) piece = board.piece_at(square) # Correct square color for orientation if (rank + file) % 2 == 1: bg = LIGHT_SQUARE_BG else: bg = DARK_SQUARE_BG if piece: fg = ( WHITE_PIECE_COLOR if piece.color == chess.WHITE else BLACK_PIECE_COLOR ) symbol = UNICODE_PIECES[piece.symbol()] board_str += f"{bg}{fg} {symbol} {RESET}" else: board_str += f"{bg} {RESET}" board_str += "\n" # Files labels in proper order if white_to_move: files_label = "a b c d e f g h" else: files_label = "h g f e d c b a" board_str += " " + files_label + "\n" return board_str if __name__ == "__main__": # Example usage: board = chess.Board() fen = board.fen() print(colored_unicode_board(fen)) # Try switching turns for demo: print(colored_unicode_board())