A classic Snake game written in Python with Pygame, following the Mode B (Small Reusable Project) architecture: the pure game rules are completely separated from the rendering code, so they can be unit tested without opening a window.
Why
pygame-ce? The originalpygamepackage does not yet ship prebuilt wheels for Python 3.14.pygame-ce(Community Edition) is a drop-in replacement with the sameimport pygameAPI and is the recommended choice for modern Python versions. See Installation below for alternatives.
- Wrap-around walls (passing through one edge makes the snake appear on the opposite edge).
- Game over only on self-collision — never on wall hit.
- Snake grows and score increases by 1 for every food eaten.
- Speed gradually increases up to a configurable cap.
- Opposite-direction input is ignored to prevent instant suicide.
- Press Space or Enter on the Game Over screen to restart.
- Audio — synthesized eat sound (ascending tone), synthesized game-over sound (descending tone), and background 8-bit music loop.
- Audio gracefully degrades if hardware is unavailable.
| Key | Action |
|---|---|
| Arrow keys / WASD | Change snake direction |
| Space / Enter | Restart after Game Over |
| Esc / Q / window ✕ | Quit |
- Python 3.10+ (tested on 3.14)
pygame-ce2.5+ (or the originalpygame2.5+ on Python ≤ 3.13)numpy2+ (for sound synthesis)pytest8+ (for running tests)
You can use any of the following setups; pick the one that matches your environment.
uv sync # creates .venv and installs deps from pyproject.toml
uv run python src/main.pypython -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
pip install pygame-ce numpy pytest
python src/main.pypip install --user pygame-ce numpy pytest
python src/main.pyIf you are on Python 3.10–3.13 you can substitute the dependency:
pip install pygame numpy pytest…and edit pyproject.toml to declare pygame>=2.5.0 instead of
pygame-ce. The code itself does not need to change.
python src/main.pyA 600×480 window opens. The snake starts in the middle, moving right.
The test suite covers wrapping, self-collision, eating, the speed cap, opposite-direction input, the win condition, and reset behaviour.
python -m pytestor, if you use uv:
uv run pytestExpected output: 24 passed.
snake-game/
├── README.md
├── AGENTS.md # meta-prompt for future AI agents
├── CREDITS.md # audio attribution
├── pyproject.toml
├── .gitignore
├── assets/
│ └── audio/
│ └── background_music.mp3 # 8-bit chiptune loop (CC0)
├── docs/
│ └── agent-instructions/
│ ├── coding-rules.md
│ ├── build-rules.md
│ └── audio-rules.md # audio implementation guidelines
├── src/
│ ├── __init__.py
│ ├── main.py # entry point, game loop, input handling, audio init
│ ├── config.py # tunables: grid, speeds, colors, audio paths
│ ├── entities.py # Snake, Food, Direction, GameState
│ ├── game_logic.py # PURE rules (no pygame imports)
│ ├── audio_synthesis.py # numpy sine-wave sound generators
│ ├── audio_service.py # AudioService: play/stop music + SFX
│ └── renderer.py # pygame drawing code
└── tests/
├── test_game_logic.py # 14 unit tests, all pygame-free
└── test_audio_service.py # 10 audio synthesis + service tests
# Install PyInstaller
uv add --dev pyinstaller
# Build executable
uv run pyinstaller --onefile --windowed src/main.py --add-data "assets/audio;assets/audio" --name snake_game
# The .exe will be in the dist/ folderBackground music: "Freddie Friday Loop" by iamoneabe (CC0, no attribution
required). See CREDITS.md for full details.
- Volume controls & mute toggle.
- Multiple music tracks.
- Audio settings persistence.
- Persistent high-score storage.
- In-game statistics tracking.
.exedistribution via PyInstaller — seedocs/agent-instructions/build-rules.md.