Back to Portfolio

snake*search.exe

$ cat README.md
A classic snake game implementation with intelligent pathfinding using the A* algorithm. The snake automatically finds the shortest path to food while avoiding obstacles and its own body.
README.md
source/
assets/
tests/
demo.mp4

Snake*Search: A Journey Through Algorithmic Game Design

1. Conception: From Curiosity to Code

The project began with a simple question: How do game characters navigate complex environments so efficiently? During my studies in distributed systems and graph algorithms, I became fascinated by pathfinding methods like DFS, BFS, and Dijkstra's Algorithm. But it was A*search—a hybrid of heuristic-driven and cost-based navigation—that stood out for its balance of speed and accuracy.

Initial Goals:

  • Implement a self-playing Snake game using A*.
  • Compare its efficiency against other algorithms (time constraints later narrowed this focus).
  • Learn Pygame to bridge theory with tangible results.

2. Building the Foundation

Phase 1: The Basic Snake

I started with a Pygame tutorial (Coder Space, 2022) to create the core mechanics:

  • Snake movement (grid-based, WASD controls).
  • Food spawning (random coordinates).
  • Collision detection (walls, self).

Early Struggle: The snake's movement felt rigid. To make it autonomous, I needed to replace player input with algorithmic decision-making.

The original snake game with manual controls

Phase 2: A* Integration

Key Steps:

  1. Grid Representation:
    • Treated the game window as a graph where each pixel was a node.
    • Defined neighbors (up/down/left/right) with a Manhattan distance heuristic.
  2. Path Calculation:
    • Used A* to find the shortest path from the snake's head to the food, avoiding:
      • Its own body (snake_body list).
      • Randomly placed obstacles (obstacle_positions).
  3. Dynamic Adaptation:
    • Recalculated the path after every move to account for the growing body.

Code Breakthrough:

def A_Star(start, goal, grid_size, snake_body, obstacle_positions):
    open_set = {start}
    came_from = {}  # Tracks the optimal path
    g_score = {start: 0}  # Cost from start
    f_score = {start: m_distance(start, goal)}  # Estimated total cost
    ...

3. Challenges & Iterations

Problem 1: Food Spawning in Obstacles

  • Initially, food appeared inside obstacles, causing instant collisions.
  • Solution: Added validation to regenerate food until it spawned in a valid location.

Problem 2: Algorithmic Bottlenecks

  • A* slowed when the snake grew long (many body segments to avoid).
  • Optimization: Limited path recalculation to every N frames and prioritized recent moves.

Problem 3: Visual Clarity

  • Debugging paths was hard without visual aids.
  • Fix: Added temporary debug lines to display A*'s chosen path (removed in the final version).

4. Polishing the Experience

To make the game engaging, I:

  • Added Assets: Replaced rectangles with pixel-art sprites (snake, food, obstacles).
  • Fine-Tuned Gameplay: Adjusted snake speed (time_step) and obstacle density.
  • Scoring System: +10 points per food, with a reset on collision.

Final Mechanics:

  • The snake autonomously navigates to food while dodging obstacles and its tail.
  • Obstacles reset on each game over, ensuring variability.

The A* pathfinding algorithm in action, automatically navigating the snake

5. Lessons Learned

  1. Theory vs. Practice:
    • A*'s elegance in textbooks didn't account for real-world edge cases (e.g., dead ends).
    • Debugging forced me to deeply understand heuristic trade-offs.
  2. Adaptability Matters:
    • My initial plan to compare multiple algorithms was scrapped due to time, but A* alone taught me more about optimization.
  3. User Experience:
    • Even a technical demo benefits from polish (e.g., sprites, score displays).

6. Future Directions

  1. Advanced AI:
    • Replace A* with Q-learning to let the snake learn from mistakes.
  2. Multi-Algorithm Mode:
    • Let users toggle between A*, Dijkstra, and BFS to see differences in real time.
  3. Hardware Integration:
    • Port the game to a Raspberry Pi and connect it to a physical robotic snake.

Conclusion

Snake*Search evolved from a simple coding exercise into a deep dive into algorithmic decision-making. The project honed my skills in Python, Pygame, and heuristic design, while teaching me to embrace iterative problem-solving. Most importantly, it proved that even classic games can become gateways to advanced computational thinking.

Skills Demonstrated:

⌙ Pathfinding Algorithms (A*) | Pygame Development | Debugging & Optimization | AI Fundamentals

Project Artifacts:

Code | Demo Video | Technical Write-Up

Live Demo

Score: 0

How to Play:

  • AI Mode: Watch as the A* algorithm navigates the snake through obstacles to find food
  • Player Mode: Control the snake using WASD or arrow keys
  • Objective: Collect food (pink circles) and avoid obstacles (red X's) and walls
  • A* Algorithm: In AI mode, the pathfinding algorithm calculates the optimal route to food
  • Restart: Click AI Mode or Player Mode to restart after game over