106 lines
3.0 KiB
Python
106 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
from blokus_gym.core.game import BlokusGame
|
|
|
|
# ANSI color codes for terminal rendering
|
|
ANSI_COLORS = {
|
|
0: "\033[90m", # grey (empty)
|
|
1: "\033[91m", # red
|
|
2: "\033[94m", # blue
|
|
3: "\033[93m", # yellow
|
|
4: "\033[92m", # green
|
|
}
|
|
ANSI_RESET = "\033[0m"
|
|
|
|
# Player names
|
|
PLAYER_NAMES = {1: "Red", 2: "Blue", 3: "Yellow", 4: "Green"}
|
|
|
|
|
|
def render_text_board(game: BlokusGame) -> str:
|
|
"""Render the board as a text string (no ANSI colors).
|
|
|
|
Returns a string representation of the board.
|
|
"""
|
|
lines = []
|
|
size = game.board_size
|
|
|
|
# Column headers
|
|
header = " " + " ".join(str(i % 10) for i in range(size))
|
|
lines.append(header)
|
|
|
|
for y in range(size):
|
|
row = f"{y % 10} "
|
|
for x in range(size):
|
|
cell = game.board.get_cell(x, y)
|
|
if cell == 0:
|
|
row += ". "
|
|
else:
|
|
row += f"{cell} "
|
|
lines.append(row)
|
|
|
|
# Player info
|
|
lines.append("")
|
|
for i, player in enumerate(game.players):
|
|
remaining = len(player.available_pieces)
|
|
total = len(game.piece_set.pieces)
|
|
name = PLAYER_NAMES.get(i + 1, f"Player {i + 1}")
|
|
lines.append(f"{name}: {remaining}/{total} pieces remaining, score: {player.score}")
|
|
|
|
cur_name = PLAYER_NAMES.get(game.current_player + 1, game.current_player + 1)
|
|
lines.append(f"Current player: {cur_name}")
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
def render_ansi_board(game: BlokusGame) -> str:
|
|
"""Render the board with ANSI color codes.
|
|
|
|
Returns a string with ANSI escape sequences for colored output.
|
|
"""
|
|
lines = []
|
|
size = game.board_size
|
|
|
|
# Column headers
|
|
header = " " + " ".join(str(i % 10) for i in range(size))
|
|
lines.append(header)
|
|
|
|
for y in range(size):
|
|
row = f"{y % 10} "
|
|
for x in range(size):
|
|
cell = game.board.get_cell(x, y)
|
|
color = ANSI_COLORS.get(cell, ANSI_RESET)
|
|
if cell == 0:
|
|
row += f"{color}. {ANSI_RESET}"
|
|
else:
|
|
row += f"{color}{cell} {ANSI_RESET}"
|
|
lines.append(row)
|
|
|
|
# Player info
|
|
lines.append("")
|
|
for i, player in enumerate(game.players):
|
|
remaining = len(player.available_pieces)
|
|
total = len(game.piece_set.pieces)
|
|
name = PLAYER_NAMES.get(i + 1, f"Player {i + 1}")
|
|
color = ANSI_COLORS.get(i + 1, ANSI_RESET)
|
|
lines.append(
|
|
f"{color}{name}{ANSI_RESET}: {remaining}/{total} pieces, "
|
|
f"score: {player.score}"
|
|
)
|
|
|
|
lines.append(
|
|
f"Current player: "
|
|
f"{ANSI_COLORS.get(game.current_player + 1, ANSI_RESET)}"
|
|
f"{PLAYER_NAMES.get(game.current_player + 1, game.current_player + 1)}"
|
|
f"{ANSI_RESET}"
|
|
)
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
def print_board(game: BlokusGame, use_ansi: bool = True) -> None:
|
|
"""Print the board to stdout."""
|
|
if use_ansi:
|
|
print(render_ansi_board(game))
|
|
else:
|
|
print(render_text_board(game))
|