Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

13 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Pac-Man ๐ŸŽฎ

An emoji Pac-Man game in your terminal emulator :)

shot

How to Play

Use arrow keys to move, eat all food to win.

Item Emoji Points Effect
Food ๐Ÿ’ฉ 1 Basic food
Cake ๐Ÿฐ 5 โ€”
Meat ๐Ÿฅฉ 10 โ€”
Candy ๐Ÿญ 50 Power-up! Ghosts turn ๐Ÿ˜ฐ and flee โ€” eat them for 200 pts each

You have 3 lives (โค๏ธโค๏ธโค๏ธ). Touching a normal ghost costs one life; touching a ๐Ÿ˜ฐ frightened ghost eats it instead.

Press P to pause/resume.

Get Started

Compile and run pm.c, that's it.

cc pm.c && ./a.out

Features

  • ๐Ÿ—บ๏ธ Custom map
  • ๐Ÿ‘ป Personality-based ghost AI (BFS pathfinding)
  • โšก Frame-diff incremental rendering

Ghost AI

Original Problems

The original implementation used Manhattan-distance greedy pathfinding: at each step, the ghost picks the neighbor that minimizes |dx| + |dy| to the player. This had three major issues:

  1. Blind to walls โ€” The greedy approach only looks one step ahead. When a wall sits between the ghost and player in an L-shape, the ghost oscillates against the wall because the Manhattan-optimal direction is blocked, but the second-best direction keeps pulling it back.

  2. Homogeneous behavior โ€” All ghosts use the identical strategy and target, so they cluster on the same path and block each other (the isghost() check makes trailing ghosts freeze).

  3. Fake difficulty โ€” rand() % 2 randomly skips ghost movement. This doesn't make ghosts smarter, just slower and inconsistent.

Optimization: BFS + Personality

To fix these issues, we replaced the greedy algorithm with BFS pathfinding and gave each ghost a distinct personality, inspired by the classic arcade game.

Ghost Personality Strategy Speed
๐Ÿ˜ˆ A Chase (Blinky) BFS directly to player position Every frame
๐Ÿ‘ป B Ambush (Pinky) BFS to 4 cells ahead of player Every 2 frames
๐Ÿ‘น C Random (Inky) 30% BFS to player, 70% random valid direction Every 2 frames

How BFS solves the wall-blindness problem: BFS explores the grid level by level from the ghost's position to its target. Since it considers all reachable cells, it always finds the true shortest path around walls โ€” no more oscillation. The map is at most 21ร—20 = 420 cells, so BFS completes in O(420) โ€” negligible cost even at high frame rates. The function returns the direction of the first step on the shortest path, and the ghost takes that step.

How personality solves the homogeneity problem: Instead of all ghosts targeting the player's current position, each ghost aims at a different point โ€” the player's current position, a position ahead of the player, or a random direction. This spreads ghosts across different paths and creates a more organic encirclement pattern.

How tick-based speed solves the fake-difficulty problem: Ghost speed is now controlled deterministically via a tick % speed counter rather than random skipping. This gives consistent, predictable behavior that's still tunable per ghost.

For the Ambush ghost, the target is offset 4 cells in the player's last movement direction. If that position is off the map or a wall, it falls back to the player's current position.

For the Random ghost, the 70% random walk avoids walls and adds unpredictability without being aimless.

Rendering

The game uses double-buffered frame-diff incremental rendering:

  • Two buffers: buf (current frame) and prev (previous frame)
  • Each frame, only cells that changed between buf and prev are redrawn
  • Changed cells use ANSI CSI escape sequences (\x1b[row;colH) to reposition the cursor
  • A typical frame redraws only 8โ€“10 cells instead of all 420

This reduces output from ~4 KB/frame (full redraw) to ~200 bytes/frame (diff only).

About

This program is written in pure ANSI C without any game engine or GUI framework, but the way it calculates and renders frames borrows ideas from real rendering pipelines: double-buffered frame diffing for output, and BFS for pathfinding.

LICENSE

The source code is MIT licensed and also available at git.sr.ht/~zz/pm.

About

๐Ÿ˜‹ An emoji Pac-Man game in your terminal emulator.

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Contributors

Languages