Skip to content

Commit

Permalink
Add clock highlight to indicate whose turn it is
Browse files Browse the repository at this point in the history
  • Loading branch information
trevorbayless committed Jun 18, 2024
1 parent 2a34299 commit 6af4f1c
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 8 deletions.
11 changes: 10 additions & 1 deletion src/cli_chess/core/game/game_metadata.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass
from chess import Color
from chess import Color, COLORS
from typing import Optional


Expand All @@ -18,6 +18,7 @@ class ClockMetadata:
units: str = "ms"
time: Optional[int] = None
increment: Optional[int] = None
ticking: bool = False


@dataclass
Expand All @@ -37,5 +38,13 @@ def __init__(self):
self.rated: bool = False
self.speed: Optional[str] = None

def set_clock_ticking(self, color: Optional[Color]):
if color is None:
for c in COLORS:
self.clocks[c].ticking = False
else:
self.clocks[color].ticking = True
self.clocks[not color].ticking = False

def reset(self):
self.__init__()
9 changes: 5 additions & 4 deletions src/cli_chess/core/game/online_game/online_game_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ def _update_game_metadata(self, *args, sender: Optional[EventSender] = None, dat

elif sender is EventSender.FROM_GSD:
if EventTopics.GAME_START in args:
self.game_metadata.set_clock_ticking(self.board_model.get_turn())
for color in COLOR_NAMES:
side_data = data.get(color, {})
color_as_bool = Color(COLOR_NAMES.index(color))
Expand All @@ -271,14 +272,13 @@ def _update_game_metadata(self, *args, sender: Optional[EventSender] = None, dat
color_as_bool].name = f"Stockfish level {side_data.get('aiLevel', '?')}"

self.game_metadata.clocks[color_as_bool].units = "ms"
self.game_metadata.clocks[color_as_bool].time = data.get('state', {}).get(
'wtime' if color == "white" else 'btime')
self.game_metadata.clocks[color_as_bool].increment = data.get('state', {}).get(
'winc' if color == "white" else 'binc')
self.game_metadata.clocks[color_as_bool].time = data.get('state', {}).get('wtime' if color == "white" else 'btime')
self.game_metadata.clocks[color_as_bool].increment = data.get('state', {}).get('winc' if color == "white" else 'binc')

elif EventTopics.MOVE_MADE in args:
self.game_metadata.clocks[WHITE].time = data.get('wtime')
self.game_metadata.clocks[BLACK].time = data.get('btime')
self.game_metadata.set_clock_ticking(self.board_model.get_turn()) if EventTopics.GAME_END not in args else None

self._notify_game_model_updated(*args, **kwargs)
except Exception as e:
Expand All @@ -292,6 +292,7 @@ def _report_game_over(self, status: str, winner: str) -> None:
self._game_end()
self.game_metadata.game_status.status = status # status list can be found in lila status.ts
self.game_metadata.game_status.winner = winner
self.game_metadata.set_clock_ticking(None)
self._notify_game_model_updated(EventTopics.GAME_END)

def cleanup(self) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def _update_game_metadata(self, *args, data: Optional[Dict] = None) -> None:
self.game_metadata.players[color_as_bool].name = f"Stockfish level {ai_level}"

if EventTopics.MOVE_MADE in args:
self.game_metadata.set_clock_ticking(self.board_model.get_turn())
for color in COLORS:
self.game_metadata.clocks[color].units = "sec"
self.game_metadata.clocks[color].time = data.get('wc' if color == WHITE else 'bc')
Expand Down
4 changes: 2 additions & 2 deletions src/cli_chess/modules/clock/clock_presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def update(self, *args, **kwargs) -> None:
if (EventTopics.GAME_START in args or EventTopics.GAME_END in args or
EventTopics.MOVE_MADE in args or EventTopics.BOARD_ORIENTATION_CHANGED in args):
orientation = self.model.board_model.get_board_orientation()
self.view_upper.update(self.get_clock_display(not orientation))
self.view_lower.update(self.get_clock_display(orientation))
self.view_upper.update(self.get_clock_display(not orientation), self.model.game_metadata.clocks[not orientation].ticking)
self.view_lower.update(self.get_clock_display(orientation), self.model.game_metadata.clocks[orientation].ticking)

def get_clock_display(self, color: Color) -> str:
"""Returns the formatted clock display for the color passed in"""
Expand Down
6 changes: 5 additions & 1 deletion src/cli_chess/modules/clock/clock_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ def __init__(self, presenter: ClockPresenter, initial_time_str: str):
self._clock_control = FormattedTextControl(text=lambda: self.time_str, style="class:clock")
self._container = Box(Window(self._clock_control, align=WindowAlign.LEFT), padding=0, padding_right=1, height=D(max=1))

def update(self, time: str) -> None:
def update(self, time: str, is_ticking: bool) -> None:
"""Updates the clock using the data passed in"""
self.time_str = time
if is_ticking:
self._clock_control.style = "class:clock.ticking"
else:
self._clock_control.style = "class:clock"

def __pt_container__(self) -> Box:
"""Returns this views container"""
Expand Down
3 changes: 3 additions & 0 deletions src/cli_chess/utils/styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"player-info.pos-rating-diff": "fg:darkgreen",
"player-info.neg-rating-diff": "fg:darkred",

"clock": "fg:white",
"clock.ticking": "bg:green",

# Program styling
"menu": "bg:",
"menu.category-title": "fg:black bg:limegreen",
Expand Down

0 comments on commit 6af4f1c

Please sign in to comment.