wip: cursor blinking when selecting pieces

This commit is contained in:
Rudis Muiznieks 2022-04-30 17:16:13 -05:00
parent 0d5a55088f
commit 93e941a79e
Signed by: rudism
GPG Key ID: CABF2F86EF7884F9
4 changed files with 75 additions and 19 deletions

View File

@ -30,7 +30,7 @@ class ControlInput:
self._buttons[button].direction = Direction.INPUT self._buttons[button].direction = Direction.INPUT
self._buttons[button].pull = Pull.UP self._buttons[button].pull = Pull.UP
def get_one_shot(self, timeout = 0): def get_one_shot(self, timeout: float = 0):
started = time.time() started = time.time()
while True: while True:
time.sleep(0.05) time.sleep(0.05)

View File

@ -21,8 +21,8 @@ class Graphics:
def text(self, text, x, y, c): def text(self, text, x, y, c):
self._display.text(text, x * self.CHAR_WIDTH, y * self.LINE_HEIGHT, c) self._display.text(text, x * self.CHAR_WIDTH, y * self.LINE_HEIGHT, c)
def pixel(self, x, y, c): def pixel(self, x, y, c = None):
self._display.pixel(x, y, c) return self._display.pixel(x, y, c)
def line(self, x1, y1, x2, y2, c): def line(self, x1, y1, x2, y2, c):
self._display.line(x1, y1, x2, y2, c) self._display.line(x1, y1, x2, y2, c)

View File

@ -1,7 +1,7 @@
from typing import Optional from typing import Optional
from icecream import ic from icecream import ic
from graphics import Graphics from graphics import Graphics
from chess import Board, Outcome, Color, WHITE import chess
class Draw: class Draw:
BOARD_SIZE = 64 BOARD_SIZE = 64
@ -85,10 +85,44 @@ class Draw:
return move.upper()[:2] + "-" + move.upper()[2:] return move.upper()[:2] + "-" + move.upper()[2:]
return move return move
def draw_board(self, board: Board, player_color: Color): def _invert_pixel(self, x: int, y: int):
c = self._graphics.pixel(x, y)
c = None if c != None else 1
self._graphics.pixel(x, y, c)
def _cursor_clear(self, except_for: list[str], player_color: chess.Color):
c = 0
for row in range(8):
for col in range(8):
sqx = col if player_color == chess.WHITE else 7 - col
sqy = row if player_color == chess.BLACK else 7 - row
square = chr(sqx + 97) + str(sqy + 1)
if not (square in except_for):
# see if square is right color
sqc = self._graphics.pixel(sqx * 8, sqy * 8)
if sqc != c:
ic(square)
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: chess.Color):
sqx = ord(square[0]) - 97
sqy = int(square[1]) - 1
if player_color == chess.WHITE:
sqy = 7 - sqy
else:
sqx = 7 - sqx
for i in range(7):
self._invert_pixel(sqx * 8 + i, sqy * 8)
self._invert_pixel(sqx * 8 + i, sqy * 8 + 7)
self._invert_pixel(sqx * 8, sqy * 8 + i)
self._invert_pixel(sqx * 8 + 7, sqy * 8 + i)
def draw_board(self, board: chess.Board, player_color: chess.Color):
self._graphics.fill_rect(0, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0) self._graphics.fill_rect(0, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
nb = "".join(str(board).split()).replace(" ", "") nb = "".join(str(board).split()).replace(" ", "")
nb = nb if player_color == WHITE else nb[::-1] nb = nb if player_color == chess.WHITE else nb[::-1]
c = True c = True
for row in range(8): for row in range(8):
for col in range(8): for col in range(8):
@ -127,17 +161,25 @@ class Draw:
"you win!" if player_won else "you lose!", 12, 2, 1) "you win!" if player_won else "you lose!", 12, 2, 1)
self._graphics.show() self._graphics.show()
def draw_select(self, last_move: str, src: str, dst = None): def draw_select(self, board: chess.Board, last_move: str, player_color: chess.Color, src: Optional[str], dst: Optional[str] = None):
self._clear_info() self._clear_info()
self._graphics.text(self._format_move(last_move), 12, 0, 1) self._graphics.text(self._format_move(last_move), 12, 0, 1)
self._graphics.text("You move:", 12, 2, 1) self._graphics.text("You move:", 12, 2, 1)
if dst == None: if src != None and dst == None:
self._graphics.text("<" + src.upper() + "> - __", 12, 3, 1) self._graphics.text("<" + src.upper() + "> - __", 12, 3, 1)
else: #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._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() self._graphics.show()
def draw_game_over(self, outcome: Optional[Outcome]): def draw_game_over(self, outcome: Optional[chess.Outcome]):
self._clear_info() self._clear_info()
self._graphics.text("Game over", 12, 0, 1) self._graphics.text("Game over", 12, 0, 1)
if outcome != None: if outcome != None:
@ -145,6 +187,6 @@ class Draw:
self._graphics.text("Draw!", 12, 2, 1) self._graphics.text("Draw!", 12, 2, 1)
else: else:
self._graphics.text("Winner:", 12, 2, 1) self._graphics.text("Winner:", 12, 2, 1)
self._graphics.text("White!" if outcome.winner == WHITE else "Black!", self._graphics.text("White!" if outcome.winner == chess.WHITE else "Black!",
12, 3, 1) 12, 3, 1)
self._graphics.show() self._graphics.show()

View File

@ -1,4 +1,5 @@
from os import path from os import path
from typing import Optional
from enum import Enum, auto from enum import Enum, auto
import shutil import shutil
from icecream import ic from icecream import ic
@ -54,6 +55,11 @@ class ChessGame:
self._sf.make_moves_from_current_position([move]) self._sf.make_moves_from_current_position([move])
self._draw.draw_board(self._board, self._player_color) self._draw.draw_board(self._board, self._player_color)
def _square_sort_key(self, square: str):
# convert to number between 00 to 88
key = (int(square[1]) - 1) * 10 + ord(square[0]) - 97
return key if self._player_color == WHITE else 88 - key
def _get_sources(self): def _get_sources(self):
if len(list(self._all_moves)) == 0: if len(list(self._all_moves)) == 0:
moves = self._board.generate_legal_moves() moves = self._board.generate_legal_moves()
@ -63,7 +69,7 @@ class ChessGame:
if len(list(self._all_moves)) > 0: if len(list(self._all_moves)) > 0:
return sorted( return sorted(
list(self._all_moves), list(self._all_moves),
key=lambda x: x[::-1]) key=lambda x: self._square_sort_key(x))
return list[str]() return list[str]()
def _get_dests(self): def _get_dests(self):
@ -71,7 +77,7 @@ class ChessGame:
src = self._get_sources()[self._src_idx] src = self._get_sources()[self._src_idx]
return sorted( return sorted(
self._all_moves[src], self._all_moves[src],
key=lambda x: x[::-1]) key=lambda x: self._square_sort_key(x))
return list[str]() return list[str]()
def run(self): def run(self):
@ -79,8 +85,8 @@ class ChessGame:
self._load_saved_or_init() self._load_saved_or_init()
while True: while True:
key = None key: Optional[Button] = None
src = None src: Optional[str] = None
################ ################
# HANDLE STATE # # HANDLE STATE #
@ -91,11 +97,13 @@ class ChessGame:
# draw menu # draw menu
if self._state == GameState.MAIN_MENU: if self._state == GameState.MAIN_MENU:
self._draw.draw_board(self._board, self._player_color)
self._draw.draw_menu(self._menu_index) self._draw.draw_menu(self._menu_index)
key = self._cinput.get_one_shot() key = self._cinput.get_one_shot()
# computer makes a move # computer makes a move
elif self._state == GameState.THINKING: elif self._state == GameState.THINKING:
self._draw.draw_board(self._board, self._player_color)
self._draw.draw_thinking(self._move) self._draw.draw_thinking(self._move)
move = self._sf.get_best_move_time(self.STOCKFISH_MOVE_TIME * 1000) move = self._sf.get_best_move_time(self.STOCKFISH_MOVE_TIME * 1000)
if move != None: if move != None:
@ -113,8 +121,8 @@ class ChessGame:
srces = self._get_sources() srces = self._get_sources()
if len(srces) > 0: if len(srces) > 0:
src = srces[self._src_idx] src = srces[self._src_idx]
self._draw.draw_select(self._move, src) self._draw.draw_select(self._board, self._move, self._player_color, src)
key = self._cinput.get_one_shot() key = self._cinput.get_one_shot(0.1)
else: else:
self._state = GameState.GAME_OVER self._state = GameState.GAME_OVER
@ -122,11 +130,12 @@ class ChessGame:
elif self._state == GameState.CHOOSE_DST: elif self._state == GameState.CHOOSE_DST:
src = self._get_sources()[self._src_idx] src = self._get_sources()[self._src_idx]
dst = self._get_dests()[self._dst_idx] dst = self._get_dests()[self._dst_idx]
self._draw.draw_select(self._move, src, dst) self._draw.draw_select(self._board, self._move, self._player_color, src, dst)
key = self._cinput.get_one_shot() key = self._cinput.get_one_shot(0.1)
# game has ended # game has ended
else: else:
self._draw.draw_board(self._board, self._player_color)
self._draw.draw_game_over(self._board.outcome()) self._draw.draw_game_over(self._board.outcome())
key = self._cinput.get_one_shot() key = self._cinput.get_one_shot()
@ -134,6 +143,9 @@ class ChessGame:
# HANDLE INPUT # # HANDLE INPUT #
################ ################
if key == None:
continue
# handle user input on main menu # handle user input on main menu
if self._state == GameState.MAIN_MENU: if self._state == GameState.MAIN_MENU:
@ -166,6 +178,8 @@ class ChessGame:
# TODO: some kind of cursor indicator on board # TODO: some kind of cursor indicator on board
elif self._state == GameState.CHOOSE_SRC: elif self._state == GameState.CHOOSE_SRC:
# move between source pieces # move between source pieces
cur_src = self._get_sources()[self._src_idx]
if key == Button.DIR_D or key == Button.DIR_R: if key == Button.DIR_D or key == Button.DIR_R:
self._src_idx += 1 self._src_idx += 1
if self._src_idx >= len(self._all_moves.keys()): if self._src_idx >= len(self._all_moves.keys()):