This repository has been archived on 2022-12-29. You can view files and clone it, but cannot push or open issues or pull requests.
zeropod/plugin/chess/draw.py

195 lines
7.1 KiB
Python

from typing import Optional
from icecream import ic
from graphics import Graphics
from chess import Board, Outcome, Color, WHITE
class Draw:
BOARD_SIZE = 64
SQUARE_SIZE = 8
PIECES = {
"p": [
" . . . . . . ",
" . . ■ ■ . . ",
" . ■ - - ■ . ",
" . ■ - - ■ . ",
" . . ■ ■ . . ",
" . . . . . . "],
"r": [
" ■ ■ ■ ■ ■ ■ ",
" ■ - - - - ■ ",
" . ■ - - ■ . ",
" . ■ - - ■ . ",
" ■ - - - - ■ ",
" ■ ■ ■ ■ ■ ■ "],
"n": [
" . . ■ ■ ■ . ",
" . ■ - - - ■ ",
" ■ - - - - ■ ",
" . ■ - - - ■ ",
" . . ■ - - ■ ",
" . . ■ ■ ■ ■ "],
"b": [
" . . ■ ■ . . ",
" . ■ - - ■ . ",
" . ■ - - ■ . ",
" . ■ - - ■ . ",
" ■ - - - - ■ ",
" ■ ■ ■ ■ ■ ■ "],
"q": [
" ■ . . . . ■ ",
" ■ ■ . . ■ ■ ",
" ■ - ■ ■ - ■ ",
" ■ - - - - ■ ",
" ■ - - - - ■ ",
" ■ ■ ■ ■ ■ ■ "],
"k": [
" . . ■ ■ . . ",
" ■ ■ - - ■ ■ ",
" ■ - - - - ■ ",
" ■ ■ - - ■ ■ ",
" . ■ - - ■ . ",
" . ■ ■ ■ ■ . "],
}
MENU = [
"Play",
"Quit",
"New (W)",
"New (B)"]
def __init__(self, graphics: Graphics):
self._graphics = graphics
def _draw_piece(self, piece: list[str], white: bool, sqx, sqy, sqc):
c = 0 if sqc == 1 else 1
filled = (white and sqc == 0) or (not white and sqc == 1)
for row in range(len(piece)):
pixels = piece[row].replace(" ", "")
for col in range(len(pixels)):
x = (sqx * self.SQUARE_SIZE) + col + 1
y = (sqy * self.SQUARE_SIZE) + row + 1
pixel = pixels[col]
if pixel == '':
self._graphics.pixel(x, y, c)
elif pixel =='-':
self._graphics.pixel(x, y, c if filled else sqc)
def _clear_info(self):
self._graphics.fill_rect(
self.BOARD_SIZE, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
def _format_move(self, move: str):
if len(move) == 4:
return move.upper()[:2] + "-" + move.upper()[2:]
return move
def _invert_pixel(self, x: int, y: int):
c = self._graphics.pixel(x, y)
c = 0 if c != 0 else 1
self._graphics.pixel(x, y, c)
def _cursor_clear(self, except_for: list[str], player_color: Color):
c = 1
for row in range(8):
for col in range(8): # 0,0 w = a8 b = h1 ... 7,7 w = h1 b = a8
sqx = col if player_color == WHITE else 7 - col
sqy = 7 - row if player_color == WHITE else row
square = chr(sqx + 97) + str(sqy + 1)
if not (square in except_for):
# see if square is right color
sqc = self._graphics.pixel(col * 8, row * 8)
if sqc != c:
self._cursor(square, player_color);
c = 0 if c == 1 else 1
c = 0 if c == 1 else 1
def _cursor(self, square: str, player_color: Color):
sqx = ord(square[0]) - 97
sqy = int(square[1]) - 1
if player_color == WHITE:
sqy = 7 - sqy
else:
sqx = 7 - sqx
for i in range(8):
# top and bottom row
self._invert_pixel(sqx * 8 + i, sqy * 8)
self._invert_pixel(sqx * 8 + i, sqy * 8 + 7)
if i > 0 and i < 7:
# sides (skipping top and bottom row)
self._invert_pixel(sqx * 8, sqy * 8 + i)
self._invert_pixel(sqx * 8 + 7, sqy * 8 + i)
def draw_board(self, board: Board, player_color: Color):
self._graphics.fill_rect(0, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
nb = "".join(str(board).split()).replace(" ", "")
nb = nb if player_color == WHITE else nb[::-1]
c = True
for row in range(8):
for col in range(8):
if c:
x = col * self.SQUARE_SIZE
y = row * self.SQUARE_SIZE
self._graphics.fill_rect(x, y, self.SQUARE_SIZE, self.SQUARE_SIZE, 1)
p = nb[(row * 8) + col]
if p.lower() in self.PIECES:
self._draw_piece(
self.PIECES[p.lower()], p.isupper(), col, row, c)
c = not c
c = not c
self._graphics.show()
def draw_menu(self, menu_index: int):
self._clear_info()
self._graphics.text("Menu:", 12, 0, 1)
for i in range(len(self.MENU)):
marker = "> " if i == menu_index else " "
self._graphics.text(marker + self.MENU[i], 12, i + 2, 1)
self._graphics.show()
def draw_thinking(self, last_move: str):
self._clear_info()
self._graphics.text(self._format_move(last_move), 12, 0, 1)
self._graphics.text("Shh, I'm", 12, 2, 1)
self._graphics.text("thinking!", 12, 3, 1)
self._graphics.show()
def draw_checkmate(self, move: str, player_won: bool):
self._clear_info()
self._graphics.text(move, 12, 0, 1)
self._graphics.text("Checkmate", 12, 1, 1)
self._graphics.text(
"you win!" if player_won else "you lose!", 12, 2, 1)
self._graphics.show()
def draw_select(self, last_move: str, player_color: Color, src: Optional[str], dst: Optional[str] = None):
self._clear_info()
self._graphics.text(self._format_move(last_move), 12, 0, 1)
self._graphics.text("You move:", 12, 2, 1)
if src != None and dst == None:
self._graphics.text("<" + src.upper() + "> - __", 12, 3, 1)
self._cursor_clear([src], player_color)
self._cursor(src, player_color)
elif src != None and dst != None:
self._graphics.text(src.upper() + " - <" + dst.upper() + ">", 12, 3, 1)
self._cursor_clear([src, dst], player_color)
self._cursor(src, player_color)
self._cursor(dst, player_color)
else:
self._cursor_clear(list(), player_color)
self._graphics.show()
def draw_game_over(self, outcome: Optional[Outcome]):
self._clear_info()
self._graphics.text("Game over", 12, 0, 1)
if outcome != None:
if outcome.winner == None:
self._graphics.text("Draw!", 12, 2, 1)
else:
self._graphics.text("Winner:", 12, 2, 1)
self._graphics.text("White!" if outcome.winner == WHITE else "Black!",
12, 3, 1)
self._graphics.show()