🎮 Section 07: Input, States, and Core Game Logic
Section Summary
In this section, students finish the core gameplay flow in game.py. They add keyboard input handling, pause/gameover state transitions, timer-driven snake updates, and eat/collision game rules.
By the end of this section, students will have a playable game loop where controls, movement, score updates, and game-over checks all work together.
✅ Checklist
- [ ] Update
game.pyimports to includeDict. - [ ] Add
DIRECTION_BY_KEYbelow theDirectionalias. - [ ] Replace
handle_events()placeholder with final event flow. - [ ] Add
_handle_keydown()to process input by state. - [ ] Add
_toggle_pause()for pause/resume behavior. - [ ] Replace
step_snake()placeholder with final logic. - [ ] Run
s07_test.pyto verify controls and game-state behavior.
Core Concepts
1. Event-Driven Input
Pygame sends events into a queue. handle_events() reads every event each frame. This keeps controls responsive and ensures quit/input/timer events are handled in one place.
2. Timer Events for Snake Movement
The custom snake_tick_event controls when step_snake() runs. This keeps movement tied to S.SNAKE_TPS rather than frame rate, so gameplay speed stays stable even if rendering speed changes.
3. State Machine Thinking
The game state (playing, paused, gameover) controls what actions are allowed:
- Direction keys only affect the snake while playing.
- Pause keys toggle between playing and paused.
- Restart keys only work from gameover.
This prevents invalid actions and keeps behavior predictable.
4. Input Mapping with a Dictionary
DIRECTION_BY_KEY maps keys to movement vectors. This avoids long if/elif chains and makes control customization easier.
Because this is a new top-level mapping constant, place it near the top of game.py (with imports/type aliases), not in the middle of methods.
5. Correct Logic Order in step_snake()
Order matters: 1. Move snake. 2. Check lose conditions. 3. Check eat condition.
If this order is wrong, score and collision behavior can become inconsistent.
6. OOP Message Flow
Game coordinates "what happens next," while Snake and Food handle their own specific behavior (move, hits_self, respawn, etc.). This is a strong OOP collaboration pattern.
Code Students Will Type (game.py)
Type this code by hand so you understand how input and game logic connect.
Detailed Code Review & Key Concepts
Top-Level Input Map
DIRECTION_BY_KEYcentralizes key-to-direction mapping.- Supports both arrow keys and WASD.
This keeps input extensible and readable.
handle_events()
- Handles quit events.
- Routes keypresses to
_handle_keydown(). - Processes snake movement only when timer ticks and state is
playing.
This method is the event hub for the whole game.
_handle_keydown()
- Handles quit keys first.
- Handles pause toggle keys second.
- Handles restart only in gameover state.
- Ignores direction changes unless state is playing.
This priority order prevents conflicting behavior.
_toggle_pause()
- Flips only between
playingandpaused. - Leaves
gameoverunchanged.
This makes pause logic explicit and safe.
step_snake()
- Moves first.
- Checks wall/self lose conditions next.
- Handles eating last (grow, score, respawn).
This order ensures collision outcomes are evaluated before rewards.
Test File (s07_test.py)
Use this test file to validate controls, state transitions, and step logic.
This test file validates the new behavior in focused pieces:
- Key mapping tests confirm arrow/WASD direction vectors.
- Keydown/state tests verify direction changes, pause toggles, and restart behavior.
- Timer-event test confirms snake updates happen only while playing.
- step_snake tests verify scoring/eating, self-collision gameover, and wall-collision gameover.
Passing these tests confirms the game now has functional controls and complete core gameplay flow.

