mirror of
https://github.com/ghndrx/shellmate.git
synced 2026-02-10 06:45:02 +00:00
Simplify chess board rendering - plain text that works over SSH
- Remove complex Rich styling from board (caused rendering issues) - Use simple ASCII box drawing (+---+) instead of Unicode box chars - Use dots for dark squares, spaces for light - Plain text status display - Much more reliable over SSH terminals
This commit is contained in:
@@ -272,88 +272,66 @@ async def run_chess_game(process, session: TerminalSession, username: str, oppon
|
||||
|
||||
def render_board():
|
||||
nonlocal status_msg
|
||||
writer = ProcessWriter(session)
|
||||
console = Console(file=writer, width=session.width, height=session.height, force_terminal=True)
|
||||
|
||||
session.clear()
|
||||
|
||||
# Calculate centering
|
||||
board_width = 42
|
||||
left_pad = max(0, (session.width - board_width) // 2)
|
||||
pad = " " * left_pad
|
||||
|
||||
# Title
|
||||
console.print()
|
||||
console.print(Align.center(Text("♔ SHELLMATE CHESS ♔", style="bold cyan")))
|
||||
console.print()
|
||||
|
||||
# Board with better colors
|
||||
console.print(f"{pad} a b c d e f g h")
|
||||
console.print(f"{pad} ┌───┬───┬───┬───┬───┬───┬───┬───┐")
|
||||
# Simple text-based board that works reliably over SSH
|
||||
lines = []
|
||||
lines.append("")
|
||||
lines.append(" ♔ SHELLMATE CHESS ♔")
|
||||
lines.append("")
|
||||
lines.append(" a b c d e f g h")
|
||||
lines.append(" +---+---+---+---+---+---+---+---+")
|
||||
|
||||
for rank in range(7, -1, -1):
|
||||
row = f"{pad}{rank + 1} │"
|
||||
row = f" {rank + 1} |"
|
||||
for file in range(8):
|
||||
square = chess.square(file, rank)
|
||||
piece = board.piece_at(square)
|
||||
|
||||
is_light = (rank + file) % 2 == 1
|
||||
# Green theme for board
|
||||
if is_light:
|
||||
bg = "on #769656" # Light green
|
||||
else:
|
||||
bg = "on #4a7c3f" # Dark green
|
||||
|
||||
if piece:
|
||||
char = PIECES.get(piece.symbol(), '?')
|
||||
# White pieces in white/cream, black pieces in dark
|
||||
if piece.color == chess.WHITE:
|
||||
fg = "#ffffff bold"
|
||||
else:
|
||||
fg = "#1a1a1a bold"
|
||||
row += f"[{fg} {bg}] {char} [/]│"
|
||||
row += f" {char} |"
|
||||
else:
|
||||
row += f"[{bg}] [/]│"
|
||||
# Use dots for dark squares, spaces for light
|
||||
is_light = (rank + file) % 2 == 1
|
||||
row += " . |" if not is_light else " |"
|
||||
|
||||
row += f" {rank + 1}"
|
||||
console.print(row)
|
||||
|
||||
if rank > 0:
|
||||
console.print(f"{pad} ├───┼───┼───┼───┼───┼───┼───┼───┤")
|
||||
lines.append(row)
|
||||
lines.append(" +---+---+---+---+---+---+---+---+")
|
||||
|
||||
console.print(f"{pad} └───┴───┴───┴───┴───┴───┴───┴───┘")
|
||||
console.print(f"{pad} a b c d e f g h")
|
||||
console.print()
|
||||
lines.append(" a b c d e f g h")
|
||||
lines.append("")
|
||||
|
||||
# Status panel
|
||||
# Center the board
|
||||
board_width = 42
|
||||
left_pad = max(0, (session.width - board_width) // 2)
|
||||
pad = " " * left_pad
|
||||
|
||||
for line in lines:
|
||||
session.write(pad + line + "\r\n")
|
||||
|
||||
# Use Rich only for the status panel (simpler)
|
||||
|
||||
# Simple status display
|
||||
turn = "White ♔" if board.turn == chess.WHITE else "Black ♚"
|
||||
turn_style = "bold white" if board.turn == chess.WHITE else "bold"
|
||||
|
||||
status_lines = []
|
||||
status_lines.append(f"[{turn_style}]{turn} to move[/]")
|
||||
session.write(pad + f" {turn} to move\r\n")
|
||||
|
||||
if board.is_check():
|
||||
status_lines.append("[red bold]⚠️ CHECK![/red bold]")
|
||||
session.write(pad + " *** CHECK! ***\r\n")
|
||||
|
||||
if move_history:
|
||||
last_moves = move_history[-3:]
|
||||
status_lines.append(f"[dim]Moves: {' '.join(last_moves)}[/dim]")
|
||||
session.write(pad + f" Moves: {' '.join(last_moves)}\r\n")
|
||||
|
||||
if status_msg:
|
||||
status_lines.append(f"[yellow]{status_msg}[/yellow]")
|
||||
session.write(pad + f" {status_msg}\r\n")
|
||||
status_msg = ""
|
||||
|
||||
status_lines.append("")
|
||||
status_lines.append("[dim]Enter move (e.g. e2e4) │ [q]uit │ [r]esign[/dim]")
|
||||
|
||||
status_panel = Panel(
|
||||
"\n".join(status_lines),
|
||||
box=ROUNDED,
|
||||
border_style="blue",
|
||||
width=min(50, session.width - 4),
|
||||
title="[bold]Game Status[/bold]"
|
||||
)
|
||||
console.print(Align.center(status_panel))
|
||||
session.write("\r\n")
|
||||
session.write(pad + " Enter move (e.g. e2e4) | [q]uit | [r]esign\r\n")
|
||||
session.write(pad + " Move: ")
|
||||
session.show_cursor()
|
||||
|
||||
# Show cursor for input
|
||||
session.show_cursor()
|
||||
|
||||
@@ -92,36 +92,34 @@ def test_game_status_render():
|
||||
def test_chess_board_render():
|
||||
"""Test that chess board renders without errors."""
|
||||
output = StringIO()
|
||||
console = Console(file=output, width=80, height=24, force_terminal=True, color_system="truecolor")
|
||||
|
||||
PIECES = {
|
||||
'K': '♔', 'Q': '♕', 'R': '♖', 'B': '♗', 'N': '♘', 'P': '♙',
|
||||
'k': '♚', 'q': '♛', 'r': '♜', 'b': '♝', 'n': '♞', 'p': '♟',
|
||||
}
|
||||
|
||||
# Render a simple board section
|
||||
console.print(" a b c d e f g h")
|
||||
console.print(" ┌───┬───┬───┬───┬───┬───┬───┬───┐")
|
||||
|
||||
# Render one rank with colored squares
|
||||
row = "8 │"
|
||||
for file in range(8):
|
||||
is_light = (7 + file) % 2 == 1
|
||||
if is_light:
|
||||
bg = "on #769656"
|
||||
else:
|
||||
bg = "on #4a7c3f"
|
||||
|
||||
# Starting position pieces
|
||||
pieces_row = ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']
|
||||
char = PIECES.get(pieces_row[file], ' ')
|
||||
row += f"[#1a1a1a bold {bg}] {char} [/]│"
|
||||
# Simplified board rendering (plain text)
|
||||
lines = []
|
||||
lines.append(" a b c d e f g h")
|
||||
lines.append(" +---+---+---+---+---+---+---+---+")
|
||||
|
||||
# Render rank 8 with pieces
|
||||
pieces_row = ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']
|
||||
row = " 8 |"
|
||||
for file, piece_char in enumerate(pieces_row):
|
||||
char = PIECES.get(piece_char, '?')
|
||||
row += f" {char} |"
|
||||
row += " 8"
|
||||
console.print(row)
|
||||
lines.append(row)
|
||||
lines.append(" +---+---+---+---+---+---+---+---+")
|
||||
|
||||
for line in lines:
|
||||
output.write(line + "\n")
|
||||
|
||||
rendered = output.getvalue()
|
||||
assert "a b c" in rendered
|
||||
assert "♜" in rendered # Black rook
|
||||
assert "+---+" in rendered
|
||||
|
||||
|
||||
def test_narrow_terminal_render():
|
||||
|
||||
Reference in New Issue
Block a user