Server: implement JOIN/JOIN_ACK/JOIN_DENY handling, input parsing/relay, spawn logic, apples maintenance; fix InMemoryTransport to address specific peer; add state_full encoder

- Protocol: join parser, join_ack/deny builders, input parser, state_full builder
- Server: on_datagram dispatch, spawn per rules (prefer length 3 else 1), join deny if no cell, immediate input_broadcast relay
- Model: occupancy map and helpers
- Transport: deliver to specified peer in in-memory mode
This commit is contained in:
Vladyslav Doloman
2025-10-07 20:22:22 +03:00
parent 9043ba81c0
commit 7a5f2d8794
4 changed files with 301 additions and 12 deletions

View File

@@ -38,4 +38,18 @@ class GameState:
snakes: Dict[int, Snake] = field(default_factory=dict)
apples: List[Coord] = field(default_factory=list)
tick: int = 0
occupancy: Dict[Coord, Tuple[int, int]] = field(default_factory=dict) # cell -> (snake_id, index)
def in_bounds(self, x: int, y: int) -> bool:
return 0 <= x < self.width and 0 <= y < self.height
def cell_free(self, x: int, y: int) -> bool:
return (x, y) not in self.occupancy
def occupy_snake(self, snake: Snake) -> None:
for idx, (cx, cy) in enumerate(snake.body):
self.occupancy[(cx, cy)] = (snake.snake_id, idx)
def clear_snake(self, snake: Snake) -> None:
for (cx, cy) in list(snake.body):
self.occupancy.pop((cx, cy), None)