handle game over state

This commit is contained in:
Rudis Muiznieks 2022-04-30 11:00:14 -05:00
parent 08bd3e835c
commit 0d5a55088f
Signed by: rudism
GPG Key ID: CABF2F86EF7884F9
2 changed files with 56 additions and 21 deletions

View File

@ -1,6 +1,7 @@
from typing import Optional
from icecream import ic from icecream import ic
from graphics import Graphics from graphics import Graphics
from chess import Board, Color, WHITE from chess import Board, Outcome, Color, WHITE
class Draw: class Draw:
BOARD_SIZE = 64 BOARD_SIZE = 64
@ -79,11 +80,15 @@ class Draw:
self._graphics.fill_rect( self._graphics.fill_rect(
self.BOARD_SIZE, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0) 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 draw_board(self, board: Board, player_color: Color): def draw_board(self, board: Board, player_color: 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 == WHITE else nb[::-1]
ic(player_color, nb)
c = True c = True
for row in range(8): for row in range(8):
for col in range(8): for col in range(8):
@ -109,7 +114,7 @@ class Draw:
def draw_thinking(self, last_move: str): def draw_thinking(self, last_move: str):
self._clear_info() self._clear_info()
self._graphics.text(last_move, 12, 0, 1) self._graphics.text(self._format_move(last_move), 12, 0, 1)
self._graphics.text("Shh, I'm", 12, 2, 1) self._graphics.text("Shh, I'm", 12, 2, 1)
self._graphics.text("thinking!", 12, 3, 1) self._graphics.text("thinking!", 12, 3, 1)
self._graphics.show() self._graphics.show()
@ -124,10 +129,22 @@ class Draw:
def draw_select(self, last_move: str, src: str, dst = None): def draw_select(self, last_move: str, src: str, dst = None):
self._clear_info() self._clear_info()
self._graphics.text(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 dst == None:
self._graphics.text("<" + src + "> - __", 12, 3, 1) self._graphics.text("<" + src.upper() + "> - __", 12, 3, 1)
else: else:
self._graphics.text(src + " - <" + dst + ">", 12, 3, 1) self._graphics.text(src.upper() + " - <" + dst.upper() + ">", 12, 3, 1)
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() self._graphics.show()

View File

@ -54,6 +54,26 @@ 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 _get_sources(self):
if len(list(self._all_moves)) == 0:
moves = self._board.generate_legal_moves()
mvarray = map(lambda m: [Move.uci(m)[0:2], Move.uci(m)[2:4]], moves)
for src, dst in list(mvarray):
self._all_moves.setdefault(src, []).append(dst)
if len(list(self._all_moves)) > 0:
return sorted(
list(self._all_moves),
key=lambda x: x[::-1])
return list[str]()
def _get_dests(self):
if self._src_idx < len(list(self._all_moves)):
src = self._get_sources()[self._src_idx]
return sorted(
self._all_moves[src],
key=lambda x: x[::-1])
return list[str]()
def run(self): def run(self):
# either load the save game or start a new one # either load the save game or start a new one
self._load_saved_or_init() self._load_saved_or_init()
@ -66,6 +86,9 @@ class ChessGame:
# HANDLE STATE # # HANDLE STATE #
################ ################
if self._board.is_game_over() and self._state != GameState.MAIN_MENU:
self._state = GameState.GAME_OVER
# draw menu # draw menu
if self._state == GameState.MAIN_MENU: if self._state == GameState.MAIN_MENU:
self._draw.draw_menu(self._menu_index) self._draw.draw_menu(self._menu_index)
@ -74,7 +97,6 @@ class ChessGame:
# computer makes a move # computer makes a move
elif self._state == GameState.THINKING: elif self._state == GameState.THINKING:
self._draw.draw_thinking(self._move) self._draw.draw_thinking(self._move)
# TODO: check game over
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:
self._make_move(move) self._make_move(move)
@ -88,13 +110,9 @@ class ChessGame:
# user picks source piece # user picks source piece
elif self._state == GameState.CHOOSE_SRC: elif self._state == GameState.CHOOSE_SRC:
if len(list(self._all_moves)) == 0: srces = self._get_sources()
moves = self._board.generate_legal_moves() if len(srces) > 0:
mvarray = map(lambda m: [Move.uci(m)[0:2], Move.uci(m)[2:4]], moves) src = srces[self._src_idx]
for src, dst in list(mvarray):
self._all_moves.setdefault(src, []).append(dst)
if len(list(self._all_moves)) > 0:
src = list(self._all_moves)[self._src_idx]
self._draw.draw_select(self._move, src) self._draw.draw_select(self._move, src)
key = self._cinput.get_one_shot() key = self._cinput.get_one_shot()
else: else:
@ -102,13 +120,14 @@ class ChessGame:
# user picks dest square # user picks dest square
elif self._state == GameState.CHOOSE_DST: elif self._state == GameState.CHOOSE_DST:
src = list(self._all_moves)[self._src_idx] src = self._get_sources()[self._src_idx]
dst = self._all_moves[src][self._dst_idx] dst = self._get_dests()[self._dst_idx]
self._draw.draw_select(self._move, src, dst) self._draw.draw_select(self._move, src, dst)
key = self._cinput.get_one_shot() key = self._cinput.get_one_shot()
# game has ended # game has ended
elif self._state == GameState.GAME_OVER: else:
self._draw.draw_game_over(self._board.outcome())
key = self._cinput.get_one_shot() key = self._cinput.get_one_shot()
################ ################
@ -162,6 +181,7 @@ class ChessGame:
# move to destination picker # move to destination picker
elif key == Button.BTN_B: elif key == Button.BTN_B:
self._dst_idx = 0
self._state = GameState.CHOOSE_DST self._state = GameState.CHOOSE_DST
# handle user input when selecting dest piece # handle user input when selecting dest piece
@ -183,14 +203,12 @@ class ChessGame:
# make the move # make the move
elif key == Button.BTN_B: elif key == Button.BTN_B:
dst = self._all_moves[src][self._dst_idx] src = self._get_sources()[self._src_idx]
dst = self._get_dests()[self._dst_idx]
self._make_move(src + dst) self._make_move(src + dst)
# TODO: check game over
self._state = GameState.THINKING self._state = GameState.THINKING
# handle user input on game over # handle user input on game over
else: else:
if key == Button.BTN_A or key == Button.BTN_B: if key == Button.BTN_A or key == Button.BTN_B:
self._state = GameState.MAIN_MENU self._state = GameState.MAIN_MENU