Change terminology game state -> game dump

This commit is contained in:
Eden Kirin
2023-03-30 11:32:16 +02:00
parent 48cb1a3798
commit 413e395a75
7 changed files with 40 additions and 35 deletions

View File

@ -104,7 +104,6 @@ actor "Player 1" as P1
actor "Player 2" as P2 actor "Player 2" as P2
actor "Player 3" as P3 actor "Player 3" as P3
package Masterpiece #seashell { package Masterpiece #seashell {
rectangle "FairHopper Game Server" #lightcyan { rectangle "FairHopper Game Server" #lightcyan {
usecase API as "API Server" usecase API as "API Server"

View File

@ -5,7 +5,7 @@ from typing import Optional
from hopper.enums import Direction, PlayerMoveResult from hopper.enums import Direction, PlayerMoveResult
from hopper.errors import Collision, PositionOutOfBounds from hopper.errors import Collision, PositionOutOfBounds
from hopper.interfaces import SendGameStateInterface from hopper.interfaces import SendGameDumpInterface
from hopper.models.board import ( from hopper.models.board import (
BOARD_DUMP_CHARS, BOARD_DUMP_CHARS,
BoardLayout, BoardLayout,
@ -23,7 +23,7 @@ from settings import settings
class GameEngine: class GameEngine:
def __init__( def __init__(
self, board: GameBoard, ws_server: Optional[SendGameStateInterface] = None self, board: GameBoard, ws_server: Optional[SendGameDumpInterface] = None
) -> None: ) -> None:
self.board = board self.board = board
self.ws_server = ws_server self.ws_server = ws_server
@ -74,7 +74,7 @@ class GameEngine:
self.__debug_print_board() self.__debug_print_board()
if self.ws_server: if self.ws_server:
await self.ws_server.send_game_state() await self.ws_server.send_game_dump()
await asyncio.sleep(settings.game.MOVE_DELAY) await asyncio.sleep(settings.game.MOVE_DELAY)
return player return player
@ -136,7 +136,7 @@ class GameEngine:
logging.info(f"Player {player} reached destination!") logging.info(f"Player {player} reached destination!")
if self.ws_server: if self.ws_server:
await self.ws_server.send_game_state() await self.ws_server.send_game_dump()
self.__debug_print_board() self.__debug_print_board()
@ -168,7 +168,7 @@ class GameEngineFactory:
board_width: int, board_width: int,
board_height: int, board_height: int,
obstacle_count: int = 0, obstacle_count: int = 0,
ws_server: Optional[SendGameStateInterface] = None, ws_server: Optional[SendGameDumpInterface] = None,
) -> GameEngine: ) -> GameEngine:
board = GameBoard( board = GameBoard(
width=board_width, width=board_width,
@ -194,7 +194,7 @@ class GameEngineFactory:
@staticmethod @staticmethod
def create_default( def create_default(
ws_server: Optional[SendGameStateInterface] = None, ws_server: Optional[SendGameDumpInterface] = None,
) -> GameEngine: ) -> GameEngine:
return GameEngineFactory.create( return GameEngineFactory.create(
board_width=settings.board.WIDTH, board_width=settings.board.WIDTH,

View File

@ -18,3 +18,9 @@ class ObjectType(str, Enum):
class PlayerMoveResult(Enum): class PlayerMoveResult(Enum):
OK = auto() OK = auto()
DESTINATION_REACHED = auto() DESTINATION_REACHED = auto()
class GameState(Enum):
RUNNING = auto()
LOCKED_FOR_PRODUCT_SELECTION = auto()
ENDGAME = auto()

View File

@ -1,6 +1,6 @@
from typing import Protocol from typing import Protocol
class SendGameStateInterface(Protocol): class SendGameDumpInterface(Protocol):
async def send_game_state(self) -> None: async def send_game_dump(self) -> None:
... ...

View File

@ -15,12 +15,12 @@ class LayerDto(BaseModel):
name: str name: str
objects: list[LayerObjectDto] objects: list[LayerObjectDto]
class GameStatePlayerDto(PlayerDto): class GameDumpPlayerDto(PlayerDto):
reached_destination: bool reached_destination: bool
class GameStateDto(BaseModel): class GameDumpDto(BaseModel):
board: BoardDto board: BoardDto
destination: DestinationDto destination: DestinationDto
players: list[GameStatePlayerDto] players: list[GameDumpPlayerDto]
layers: list[LayerDto] layers: list[LayerDto]

View File

@ -5,7 +5,7 @@ import time
from threading import Thread from threading import Thread
from typing import Optional from typing import Optional
from hopper.interfaces import SendGameStateInterface from hopper.interfaces import SendGameDumpInterface
from hopper.models.player import PlayerList from hopper.models.player import PlayerList
from settings import settings from settings import settings
@ -14,7 +14,7 @@ class InactivityWatchdog(Thread):
def __init__( def __init__(
self, self,
players: PlayerList, players: PlayerList,
ws_server: Optional[SendGameStateInterface] = None, ws_server: Optional[SendGameDumpInterface] = None,
*args, *args,
**kwargs, **kwargs,
) -> None: ) -> None:
@ -38,7 +38,7 @@ class InactivityWatchdog(Thread):
seconds=settings.inacivity_watchdog.KICK_TIMEOUT seconds=settings.inacivity_watchdog.KICK_TIMEOUT
) )
send_game_state = False send_game_dump = False
for player in self.players: for player in self.players:
if ( if (
@ -48,7 +48,7 @@ class InactivityWatchdog(Thread):
): ):
player.active = False player.active = False
logging.info(f"Player {player} set as inactive") logging.info(f"Player {player} set as inactive")
send_game_state = True send_game_dump = True
# safe remove from list # safe remove from list
n = 0 n = 0
@ -57,18 +57,18 @@ class InactivityWatchdog(Thread):
if player.can_be_deactivated and player.last_seen < kick_threshold: if player.can_be_deactivated and player.last_seen < kick_threshold:
self.players.pop(n) self.players.pop(n)
logging.info(f"Player {player} kicked out") logging.info(f"Player {player} kicked out")
send_game_state = True send_game_dump = True
else: else:
n += 1 n += 1
if send_game_state: if send_game_dump:
self.send_game_state() self.send_game_dump()
def send_game_state(self): def send_game_dump(self):
if not self.ws_server: if not self.ws_server:
return return
logging.info("Sending WS game state") logging.info("Sending WS game dump")
asyncio.run(self.ws_server.send_game_state()) asyncio.run(self.ws_server.send_game_dump())
def stop(self) -> None: def stop(self) -> None:
self.stopped = True self.stopped = True

View File

@ -7,7 +7,7 @@ import websockets
from websockets import WebSocketServerProtocol from websockets import WebSocketServerProtocol
from websockets.exceptions import ConnectionClosedOK from websockets.exceptions import ConnectionClosedOK
from hopper.models.ws_dto import GameStateDto from hopper.models.ws_dto import GameDumpDto
from settings import settings from settings import settings
@ -18,8 +18,8 @@ class WSServer(Thread):
logging.info(f"Add client: {websocket.id}") logging.info(f"Add client: {websocket.id}")
try: try:
# send initial game state to connected client # send initial game dump to connected client
await self.send_game_state_to_client(websocket) await self.send_game_dump_to_client(websocket)
# loop and do nothing while client is connected # loop and do nothing while client is connected
connected = True connected = True
while connected: while connected:
@ -32,36 +32,36 @@ class WSServer(Thread):
self.connected_clients.remove(websocket) self.connected_clients.remove(websocket)
logging.info(f"Remove client: {websocket.id}") logging.info(f"Remove client: {websocket.id}")
def _create_game_state_message(self) -> str: def _create_game_dump_message(self) -> str:
# avoid circular imports # avoid circular imports
from hopper.api.dependencies import get_game_engine from hopper.api.dependencies import get_game_engine
engine = get_game_engine() engine = get_game_engine()
game_state = GameStateDto( game_dump = GameDumpDto(
board=engine.board, board=engine.board,
destination=engine.board.destination, destination=engine.board.destination,
players=engine.players, players=engine.players,
layers=engine.get_board_layout().layers, layers=engine.get_board_layout().layers,
) )
return json.dumps(game_state.dict()) return json.dumps(game_dump.dict())
async def send_game_state_to_client( async def send_game_dump_to_client(
self, websocket: WebSocketServerProtocol self, websocket: WebSocketServerProtocol
) -> None: ) -> None:
"""Send game state to the client""" """Send game dump to the client"""
message = self._create_game_state_message() message = self._create_game_dump_message()
logging.debug(f"Sending game state to client: {websocket.id}") logging.debug(f"Sending game dump to client: {websocket.id}")
await websocket.send(message) await websocket.send(message)
async def send_game_state(self) -> None: async def send_game_dump(self) -> None:
"""Broadcast game state to all connected clients""" """Broadcast game state to all connected clients"""
if not self.connected_clients: if not self.connected_clients:
return return
message = self._create_game_state_message() message = self._create_game_dump_message()
logging.debug( logging.debug(
f"Sending game state to clients: {self.connected_clients}: {message}" f"Sending game dump to clients: {self.connected_clients}: {message}"
) )
for client in self.connected_clients: for client in self.connected_clients:
await client.send(message) await client.send(message)