From c657415bf0765bb1a326872fdeec72aa96e50de2 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Thu, 13 Aug 2026 03:41:03 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=20SessionState?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mind_reader/ui/views/session_view.py | 264 +++++++++++++++-------- 1 file changed, 176 insertions(+), 88 deletions(-) diff --git a/src/mind_reader/ui/views/session_view.py b/src/mind_reader/ui/views/session_view.py index 80ef40f..65b90f5 100644 --- a/src/mind_reader/ui/views/session_view.py +++ b/src/mind_reader/ui/views/session_view.py @@ -69,12 +69,25 @@ class PlayerRole(Enum): @dataclass(frozen=True) class MoveResult: step_index: int - setter_direction: Optional[ArrowDirection] = None - setter_card_state: Optional[CardState] = None + setter_direction: ArrowDirection + setter_card_state: CardState guesser_direction: Optional[ArrowDirection] = None guesser_card_state: Optional[CardState] = None +@dataclass(frozen=True) +class CardData: + direction: Optional[ArrowDirection] + state: CardState + + +@dataclass(frozen=True) +class StepData: + index: int + setter: CardData + guesser: CardData + + @dataclass class Player: name: str @@ -88,18 +101,70 @@ class SessionState: remote_player: Player, sequence_length: int = 20, ): - self._sequence_length = sequence_length - self._local_player = local_player self._remote_player = remote_player - self._completed_step_count: int = 0 - self._step_state: StepState = StepState.WAITING_FOR_SETTER - + self._sequence_length = sequence_length self._setter_moves: list[ArrowDirection] = [] self._guesser_moves: list[ArrowDirection] = [] - self._stats: Optional[SessionStats] = None + self._step_state: StepState = StepState.WAITING_FOR_SETTER + + @property + def _completed_move_count(self): + return len(self._guesser_moves) + + def _get_setter_card_state(self, index: int) -> CardState: + current_index = len(self._setter_moves) + + if index > current_index: + return CardState.SETTER_NOT_SET + + elif index == current_index: + if self._step_state == StepState.WAITING_FOR_GUESSER: + if self._local_player.role == PlayerRole.SETTER: + return CardState.SETTER_REVEALED + else: + return CardState.SETTER_HIDDEN + + return CardState.SETTER_REVEALED + + def _get_guesser_card_state(self, index: int) -> CardState: + completed_move_count = self._completed_move_count + + if index > completed_move_count: + return CardState.GUESSER_DISABLED + + elif index == completed_move_count: + if self._step_state == StepState.WAITING_FOR_GUESSER: + return CardState.GUESSER_WAITING + else: + return CardState.GUESSER_DISABLED + + else: + setter_move = self._setter_moves[index] + guesser_move = self._guesser_moves[index] + if setter_move == guesser_move: + return CardState.GUESSER_CORRECT + else: + return CardState.GUESSER_WRONG + + def start_session(self) -> None: + index = 0 + pub.sendMessage( + "session.session_started", + step=StepData( + index=index, + setter=CardData( + direction=None, + state=self._get_setter_card_state(index), + ), + guesser=CardData( + direction=None, + state=self._get_guesser_card_state(index), + ), + ), + ) def setter_move(self, direction: ArrowDirection) -> bool: if self._step_state != StepState.WAITING_FOR_SETTER: @@ -108,20 +173,22 @@ class SessionState: self._setter_moves.append(direction) self._step_state = StepState.WAITING_FOR_GUESSER - step_index = len(self._setter_moves) - 1 - result = MoveResult( - step_index=step_index, - setter_direction=direction, - setter_card_state=self.get_setter_card_state(step_index), - ) - - pub.sendMessage("session.setter_moved", result=result) + index = len(self._setter_moves) - 1 pub.sendMessage( - "session.step_state_changed", - step_state=self._step_state, + "session.setter_moved", + step=StepData( + index=index, + setter=CardData( + direction=direction, + state=self._get_setter_card_state(index), + ), + guesser=CardData( + direction=direction, + state=self._get_guesser_card_state(index), + ), + ), ) - return True def guesser_move(self, direction: ArrowDirection) -> bool: @@ -129,28 +196,47 @@ class SessionState: return False self._guesser_moves.append(direction) - self._completed_step_count += 1 - step_index = len(self._guesser_moves) - 1 - - result = MoveResult( - step_index=step_index, - setter_direction=self._setter_moves[-1], - setter_card_state=self.get_setter_card_state(step_index), - guesser_direction=self._guesser_moves[-1], - guesser_card_state=self.get_guesser_card_state(step_index), - ) - - pub.sendMessage("session.guesser_moved", result=result) - - if self._completed_step_count < self._sequence_length: + if self._completed_move_count < self._sequence_length: self._step_state = StepState.WAITING_FOR_SETTER - pub.sendMessage( - "session.step_state_changed", - step_state=self._step_state, - ) else: self._step_state = StepState.SESSION_FINISHED + + index = len(self._guesser_moves) - 1 + + pub.sendMessage( + "session.guesser_moved", + step=StepData( + index=index, + setter=CardData( + direction=self._setter_moves[index], + state=self._get_setter_card_state(index), + ), + guesser=CardData( + direction=self._guesser_moves[index], + state=self._get_guesser_card_state(index), + ), + ), + ) + + next = index + 1 + + pub.sendMessage( + "session.step_closed", + step=StepData( + index=next, + setter=CardData( + direction=None, + state=self._get_setter_card_state(next), + ), + guesser=CardData( + direction=None, + state=self._get_guesser_card_state(next), + ), + ), + ) + + if self._step_state == StepState.SESSION_FINISHED: pub.sendMessage("session.session_finished") return True @@ -172,36 +258,6 @@ class SessionState: case StepState.SESSION_FINISHED: return False - def get_setter_card_state(self, step_index: int) -> CardState: - setter_step_index = len(self._setter_moves) + 1 - - if step_index > setter_step_index: - return CardState.SETTER_NOT_SET - - if step_index == setter_step_index: - if self._step_state == StepState.WAITING_FOR_GUESSER: - if self._local_player.role == PlayerRole.SETTER: - return CardState.SETTER_REVEALED - else: - return CardState.SETTER_HIDDEN - - return CardState.SETTER_REVEALED - - def get_guesser_card_state(self, step_index: int) -> CardState: - if step_index > self._completed_step_count: - return CardState.GUESSER_DISABLED - - elif step_index == self._completed_step_count: - return CardState.GUESSER_WAITING - - else: - guesser_move = self._guesser_moves[step_index] - setter_move = self._setter_moves[step_index] - if guesser_move == setter_move: - return CardState.GUESSER_CORRECT - else: - return CardState.GUESSER_WRONG - @property def setter_name(self) -> str: if self._local_player.role == PlayerRole.SETTER: @@ -217,7 +273,7 @@ class SessionState: return self._remote_player.name @property - def sequence_lenght(self) -> int: + def sequence_length(self) -> int: return self._sequence_length @@ -330,7 +386,7 @@ class SessionPanel(wx.Panel): self._setter_name = self._state.setter_name self._guesser_name = self._state.guesser_name - self._sequence_length = self._state.sequence_lenght + self._sequence_length = self._state.sequence_length self._setter_sequence: list[Card] = [] self._guesser_sequence: list[Card] = [] @@ -340,9 +396,10 @@ class SessionPanel(wx.Panel): self._setup() self._fit_parent_frame() + pub.subscribe(self._on_session_started, "session.session_started") pub.subscribe(self._on_setter_moved, "session.setter_moved") pub.subscribe(self._on_guesser_moved, "session.guesser_moved") - pub.subscribe(self._on_step_state_changed, "session.step_state_changed") + pub.subscribe(self._on_step_closed, "session.step_closed") pub.subscribe(self._on_session_finished, "session.session_finished") def _setup(self) -> None: @@ -463,28 +520,57 @@ class SessionPanel(wx.Panel): def _handle_arrow_input(self, direction: ArrowDirection) -> None: pass - def _on_setter_moved(self, result: MoveResult): + def _on_session_started(self, step: StepData) -> None: self.update_setter_card( - index=result.step_index, - state=result.setter_card_state or CardState.SETTER_NOT_SET, - direction=result.setter_direction, - ) - - def _on_guesser_moved(self, result: MoveResult): - self.update_setter_card( - index=result.step_index, - state=result.setter_card_state or CardState.SETTER_NOT_SET, - direction=result.setter_direction, + step.index, + step.setter.state, + step.setter.direction, ) self.update_guesser_card( - index=result.step_index, - state=result.guesser_card_state or CardState.GUESSER_DISABLED, - direction=result.guesser_direction, + step.index, + step.guesser.state, + step.guesser.direction, ) - def _on_step_state_changed(self, step_state: StepState): - pass + def _on_setter_moved(self, step: StepData) -> None: + self.update_setter_card( + step.index, + step.setter.state, + step.setter.direction, + ) + + self.update_guesser_card( + step.index, + step.guesser.state, + step.guesser.direction, + ) + + def _on_guesser_moved(self, step: StepData): + self.update_setter_card( + step.index, + step.setter.state, + step.setter.direction, + ) + + self.update_guesser_card( + step.index, + step.guesser.state, + step.guesser.direction, + ) + + def _on_step_closed(self, step: StepData): + self.update_setter_card( + step.index, + step.setter.state, + step.setter.direction, + ) + + self.update_guesser_card( + step.index, + step.guesser.state, + step.guesser.direction, + ) def _on_session_finished(self): pass @@ -536,8 +622,8 @@ class TestFrame(wx.Frame): def __init__(self): super().__init__(None, title="TestFrame") - local = Player("Бывалый", PlayerRole.GUESSER) - remote = Player("Балбес", PlayerRole.SETTER) + local = Player("Бывалый", PlayerRole.SETTER) + remote = Player("Балбес", PlayerRole.GUESSER) session = SessionState(local, remote) main_panel = SessionPanel(self, session) @@ -548,9 +634,11 @@ class TestFrame(wx.Frame): s = SessionStats(20, 1, 0, 1, 5.1) main_panel.update_statusbar(None, s) + session.start_session() session.setter_move(ArrowDirection.LEFT) session.guesser_move(ArrowDirection.LEFT) session.setter_move(ArrowDirection.LEFT) + session.guesser_move(ArrowDirection.RIGHT) if __name__ == "__main__":