|
from typing import Optional |
|
import chess |
|
|
|
WHITE_PIECE_COLOR = "\033[97m" |
|
BLACK_PIECE_COLOR = "\033[90m" |
|
LIGHT_SQUARE_BG = "\033[50m" |
|
DARK_SQUARE_BG = "\033[47m" |
|
|
|
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 |
|
|
|
|
|
if white_to_move: |
|
ranks = range(8, 0, -1) |
|
files = range(1, 9) |
|
else: |
|
ranks = range(1, 9) |
|
files = range(8, 0, -1) |
|
|
|
for rank in ranks: |
|
board_str += f"{rank} " |
|
for file in files: |
|
square = chess.square(file - 1, rank - 1) |
|
piece = board.piece_at(square) |
|
|
|
|
|
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" |
|
|
|
|
|
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__": |
|
|
|
board = chess.Board() |
|
fen = board.fen() |
|
print(colored_unicode_board(fen)) |
|
|
|
|
|
print(colored_unicode_board()) |
|
|