From cf4c2e1d5a16c8a18c6e79daf5fc735fefed6f37 Mon Sep 17 00:00:00 2001 From: Rike-Benjamin Schuppner Date: Fri, 13 Oct 2023 17:26:49 +0200 Subject: [PATCH] RF: Send final game state with to network players This makes it easier for backends/middleends to capture the last state that a player receives without having to parse it and ensure that it actually contains a state. A corollary to not doing that kind of deep package inspection is that, once a game has been started, we cannot distinguish between control messages and game info (set_initial/get_move) messages anymore and have to assume that everything is a message that needs to be forwarded to the backend player (unless we change our ZMQ protocoll to include an additional control channel). --- pelita/game.py | 11 +++++++++-- pelita/team.py | 10 ++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/pelita/game.py b/pelita/game.py index 9cdfb39e5..7c79d4f45 100644 --- a/pelita/game.py +++ b/pelita/game.py @@ -506,12 +506,18 @@ def prepare_bot_state(game_state, idx=None): """ bot_initialization = game_state.get('turn') is None and idx is not None + bot_finalization = game_state.get('turn') is not None and idx is not None if bot_initialization: # We assume that we are in get_initial phase turn = idx bot_turn = None seed = game_state['rnd'].randint(0, sys.maxsize) + elif bot_finalization: + # Called for remote players in _exit + turn = idx + bot_turn = None + seed = None else: turn = game_state['turn'] bot_turn = game_state['turn'] // 2 @@ -977,9 +983,10 @@ def check_exit_remote_teams(game_state): """ If the we are gameover, we want the remote teams to shut down. """ if game_state['gameover']: _logger.info("Gameover. Telling teams to exit.") - for team in game_state['teams']: + for idx, team in enumerate(game_state['teams']): try: - team._exit() + team_game_state = prepare_bot_state(game_state, idx=idx) + team._exit(team_game_state) except AttributeError: pass diff --git a/pelita/team.py b/pelita/team.py index 79b3e9462..f9fe5b285 100644 --- a/pelita/team.py +++ b/pelita/team.py @@ -364,10 +364,16 @@ def get_move(self, game_state): except ZMQClientError: raise - def _exit(self): + def _exit(self, game_state=None): # We only want to exit once. if getattr(self, '_sent_exit', False): return + + if game_state: + payload = {'game_state': game_state} + else: + payload = {} + try: # TODO: make zmqconnection stateful. set flag when already disconnected # For now, we simply check the state of the socket so that we do not send @@ -375,7 +381,7 @@ def _exit(self): if self.zmqconnection.socket.closed: return # TODO: Include final state with exit message - self.zmqconnection.send("exit", {}, timeout=1) + self.zmqconnection.send("exit", payload, timeout=1) self._sent_exit = True except ZMQUnreachablePeer: _logger.info("Remote Player %r is already dead during exit. Ignoring.", self)