Skip to content
asavschaeffer edited this page Mar 4, 2026 · 1 revision

Pac-Man

Second test game. Adds multi-entity dynamics, conditional rules, and spatial reasoning over Snake.


Why Pac-Man (after Snake)

  • Multiple entity types: Player, ghosts, pellets, power pellets, fruit — richer event vocabulary
  • Conditional rules: The core mechanic. Power pellet flips the ghost interaction from death to kill. This is the simplest non-trivial conditional rule and the one from the premise.
  • Enemy AI: Ghosts have distinct behaviors (chase, ambush, patrol, random in classic Pac-Man). The model must learn to predict enemy movement, not just player movement.
  • Spatial structure: Maze topology constrains movement. Corridors, intersections, dead ends — the model must learn graph structure, not just grid boundaries.
  • Phase transitions: Normal → powered → normal. Timed buff with visible countdown. Tests temporal dependency learning.
  • Well-studied: Decades of AI research on Pac-Man. Known optimal strategies, known player behavior patterns. Easy to validate results against existing literature.

What it adds over Snake

Aspect Snake Pac-Man
Entities 1 player + food 1 player + 4 ghosts + many pellets + power pellets
Conditional rules Self-collision (length) Ghost interaction (buff state)
Enemy behavior None 4 distinct AI patterns
Map structure Open grid + walls Fixed maze with corridors
State complexity Low Medium
Play styles Movement patterns Risk/reward, routing, ghost manipulation

Game Specification

Grid

  • Classic Pac-Man maze or simplified variants
  • For initial experiments: a smaller maze (15x15) with the essential topology — corridors, intersections, a few dead ends, ghost house in center
  • Walls are fixed (no destructible terrain)

Entities

  • Player: Single position, moves one cell per tick in current direction. Continues moving in last direction if no input (unlike Snake where you must always input).
  • Ghost 0-3: Each has position, current direction, and behavioral mode.
    • Chase: Targets player position (or predicted position)
    • Scatter: Targets fixed corner
    • Frightened: Moves randomly (when player is powered)
    • Eaten: Returns to ghost house (after being consumed by powered player)
  • Pellet: Static positions. Removed on collection. ~100+ per level.
  • Power Pellet: 4 per level, static positions. Triggers powered phase on collection.
  • Fruit: Spawns periodically at fixed location. Bonus points.

Actions

{UP, DOWN, LEFT, RIGHT}

No "stop" — player keeps moving in last direction. Direction change only takes effect at intersections (or immediately if reversing).

Rules

player enters pellet cell        → COLLECT, score +10, pellet removed
player enters power_pellet cell  → COLLECT, score +50, power pellet removed, POWERED phase starts
player enters ghost cell:
  if normal                      → DEATH, life lost
  if powered                     → GHOST_EATEN, score +200/400/800/1600 (combo), ghost returns to house
  if ghost is eaten (eyes)       → no interaction
player enters fruit cell         → COLLECT, bonus score
all pellets collected            → LEVEL_COMPLETE

powered phase:
  duration: N ticks (decreasing per level in classic)
  ghosts enter FRIGHTENED mode
  on expiry: ghosts return to normal mode

ghost reaches ghost house (eaten) → GHOST_RESPAWN, resumes normal behavior

State

player_pos:       (x, y)
player_dir:       {U, D, L, R}
player_alive:     bool
powered:          bool
power_timer:      int           # ticks remaining
ghost[0-3]_pos:   (x, y)
ghost[0-3]_mode:  {chase, scatter, frightened, eaten}
pellets:          set[(x, y)]   # remaining pellet positions
power_pellets:    set[(x, y)]
fruit_active:     bool
score:            int
lives:            int
level:            int

Event Vocabulary

Atomic events

# Player actions
INPUT_U, INPUT_D, INPUT_L, INPUT_R

# Movement
MOVE_PLAYER (x, y)
MOVE_GHOST0 (x, y)
MOVE_GHOST1 (x, y)
MOVE_GHOST2 (x, y)
MOVE_GHOST3 (x, y)

# Collections
COLLECT_PELLET @(x, y)
COLLECT_POWER @(x, y)
COLLECT_FRUIT

# Phase changes
POWERED_START
POWERED_END
GHOST_FRIGHTENED [ghost_id]
GHOST_NORMAL [ghost_id]

# Collisions
DEATH @(x, y) [ghost_id]           # player killed by ghost
GHOST_EATEN [ghost_id] @(x, y)     # player eats frightened ghost
GHOST_RESPAWN [ghost_id]            # ghost returns from house

# Game flow
LEVEL_COMPLETE
GAME_OVER
LIFE_LOST

Salience levels

TICK        = 0    MOVE_PLAYER, MOVE_GHOST*
COLLECTION  = 2    COLLECT_PELLET (frequent but meaningful)
PHASE       = 3    POWERED_START, POWERED_END, GHOST mode changes
CRITICAL    = 4    DEATH, GHOST_EATEN, LEVEL_COMPLETE, GAME_OVER

COLLECT_PELLET is interesting — it's frequent (100+ per level) but individually low-information. At high salience threshold, you might drop individual pellet collections and only track pellet count in snapshots.

Snapshot content

PLAYER (x, y) DIR POWERED [timer] SCORE LIVES LEVEL
GHOST0 (x, y) MODE
GHOST1 (x, y) MODE
GHOST2 (x, y) MODE
GHOST3 (x, y) MODE
PELLETS_REMAINING n
POWER_PELLETS_REMAINING n

Full pellet positions are too verbose for snapshots (100+ positions). Remaining count + power pellet positions is sufficient — the model can learn pellet density from collection events.


Expected Play Styles

Completionist / Clearer

Systematically clears all pellets in a region before moving on. Avoids ghosts. Ignores power pellets until forced. Low risk, consistent scoring.

Power Hunter

Beelines for power pellets, then immediately chases ghosts for combo points. High risk/reward. Traces show: long stretches of avoidance → power pellet → aggressive ghost pursuit → retreat.

Ghost Dodger

Stays as far from ghosts as possible. Collects pellets only in safe areas. Never uses power pellets offensively. Traces show: high correlation between ghost proximity and direction changes.

Interceptor

Manipulates ghost AI by positioning to bait them into advantageous configurations. Advanced strategy — predicts ghost movement. Traces show: deliberate movement toward then away from ghosts, herding patterns.

Fruit Camper

Prioritizes fruit spawns for bonus points. Positions near fruit spawn location. Niche but distinct.


Tokenization Challenges

Pellet tracking

100+ pellets means either:

  • Verbose snapshots (list all remaining positions)
  • No pellet state in snapshots, rely on COLLECT events to track
  • Only track count in snapshots, not positions

The hybrid approach works well here: pellet count in snapshots, individual COLLECT events for positions.

Ghost AI prediction

Each ghost has deterministic behavior in classic Pac-Man. The model should learn to predict ghost movement from mode + position. This is a non-trivial test — can the model learn 4 different movement algorithms from observing their outputs?

Combo scoring

Ghost eat combo (200 → 400 → 800 → 1600) requires counting consecutive ghost eats within a single powered phase. Tests the model's ability to track a counter that resets on phase change.

Map topology

The maze is fixed, but the model must learn which movements are legal from which positions. This is implicit in the MOVE events — if the player never moves up from position (5,3), there's probably a wall there. Can the model learn the maze from movement traces alone?


Agents for Data Generation

Random agent

Random legal move each tick. Dies constantly. Good for coverage.

Pellet greedy

Moves toward nearest pellet (BFS shortest path). Ignores ghosts. Dies when ghosts happen to intersect path.

Ghost avoidance

BFS toward nearest pellet, but won't enter any cell within Manhattan distance N of a ghost. Conservative.

Power chaser

Seeks power pellets, then switches to ghost-hunting during powered phase. Reverts to avoidance when not powered.

Hybrid / switching

Randomly switches between avoidance and power chasing. Produces mixed-style traces.


Open Questions

  • Maze complexity: Full classic Pac-Man maze or simplified? Simpler maze = smaller position vocab, faster learning, but less interesting spatial structure.
  • Ghost AI fidelity: Implement real Pac-Man ghost AI (Blinky/Pinky/Inky/Clyde) or simplified? Real AI is deterministic and well-documented, but adds implementation complexity.
  • Pellet density in tokens: Is per-pellet tracking worth the token cost, or should pellets be aggregated?
  • Multi-life episodes: Classic Pac-Man has 3 lives. Is a life loss a sub-episode boundary? Or continuous?

Clone this wiki locally