Server: per-tick simulation skeleton (inputs, movement, blocking/shrink, apple growth, wrap behavior) and basic state delta broadcast

- Input buffer rules: enqueue+consume with 180° guard (len>1)
- Movement: wrap per config; allow moving into own tail when it vacates
- Blocking: head holds, tail shrinks to min 1
- Apples: eat= grow; ensure target apples after tick
- Broadcast: send current snakes/apples as delta (placeholder for real deltas)
This commit is contained in:
Vladyslav Doloman
2025-10-07 20:27:43 +03:00
parent 7a5f2d8794
commit 991b8f3660
2 changed files with 141 additions and 1 deletions

View File

@@ -16,11 +16,33 @@ class Snake:
head: Coord
direction: Direction
body: Deque[Coord] = field(default_factory=deque) # includes head at index 0
input_buf: Deque[Direction] = field(default_factory=deque)
blocked: bool = False
@property
def length(self) -> int:
return len(self.body)
def enqueue_direction(self, new_dir: Direction, capacity: int = 3) -> None:
"""Apply input buffer rules: size<=capacity, replace last on overflow/opposite, drop duplicates."""
last_dir = self.input_buf[-1] if self.input_buf else self.direction
# Drop duplicates
if int(new_dir) == int(last_dir):
return
# Opposite of last? replace last
if (int(new_dir) ^ int(last_dir)) == 2: # 0^2,1^3,2^0,3^1 are opposites
if self.input_buf:
self.input_buf[-1] = new_dir
else:
# No buffered inputs; just add new_dir (consumption will handle 180° rule)
self.input_buf.append(new_dir)
return
# Normal append with overflow replacement
if len(self.input_buf) >= capacity:
self.input_buf[-1] = new_dir
else:
self.input_buf.append(new_dir)
@dataclass
class PlayerSession: