Skip to content

Latest commit

 

History

History
53 lines (44 loc) · 1.9 KB

File metadata and controls

53 lines (44 loc) · 1.9 KB

Engine contract (snake/engine.py)

from enum import Enum

class Direction(Enum): UP = (0, -1) # x right, y down DOWN = (0, 1) LEFT = (-1, 0) RIGHT = (1, 0)

class GameState: def init(self, width=20, height=20, rng=None, body=None, food=None, pending_growth=0): # rng: a random.Random instance. All randomness goes through it. # body: optional list of (x, y), head first. For tests. # food: optional (x, y). For tests. # pending_growth: segments still to be added. For tests. ...

snake: list          # (x, y) tuples, head first
food: tuple          # (x, y)
score: int           # foods eaten
game_over: bool

def step(self, direction) -> None
  • Default construction (no body override): the snake spawns with length 2, head at (width // 2, height // 2), tail one cell to its left, heading RIGHT, score 0, pending_growth 0, and food spawned via rng on a cell not occupied by the body.

Rules

  • One step() call is one tick. The head advances one cell.
  • 180-degree reversal input is ignored; the snake continues in its current direction (current direction = head minus neck).
  • Eating food: score += 1, pending_growth += 1, new food spawns via rng on a cell not occupied by the body.
  • Growth: while pending_growth > 0, the tail is not removed on that tick and pending_growth decrements.
  • The tail cell is vacated in the same tick the head moves. Moving the head into the cell the tail is vacating is legal, UNLESS the snake is growing that tick (tail stays put), in which case it is a collision.
  • Hitting a wall or any body cell that is not vacating = game_over. No wraparound.
  • Speed ramp is the renderer's concern (tick rate derived from score). The engine knows nothing about time.