🐍 Section 03: Build the Snake Class Skeleton

Section Summary

In this section, students build the first version of the Snake class in snake.py. They will define the snake's internal state, expose safe read-only properties, and add direction-change behavior.

By the end of this section, students will understand how to model game objects with OOP and prepare class structure before adding full movement/collision logic in the next section.

✅ Checklist

  • [ ] Create snake.py.
  • [ ] Add imports, coordinate type aliases, and the Snake class scaffold.
  • [ ] Build the snake body in __init__ using a deque.
  • [ ] Add head, body, and direction properties.
  • [ ] Add set_direction() with reverse-direction safety.
  • [ ] Add _is_reverse_direction() and occupies() helper methods.
  • [ ] Run s03_test.py to verify the skeleton behavior.

Core Concepts

1. Class Responsibility in OOP

The Snake class is responsible for snake-specific behavior and state. This includes body segments, direction, and checks related to the snake itself. Keeping this logic inside one class is clean OOP design.

2. Encapsulation with Internal Attributes

Attributes like self._body and self._dir start with _ to show they are for internal class use. This helps students separate public interface (methods/properties other files should use) from internal implementation details.

3. Why deque Is Used

deque (double-ended queue) is a great structure for snakes because the head and tail are updated often. It supports efficient operations at both ends and maps well to how snake segments behave.

4. Properties for Safe Access

head, body, and direction are properties that provide controlled read access: - head returns the current head coordinate. - body returns a tuple copy so outside code cannot directly mutate internals. - direction returns the current movement direction.

5. Direction Vectors and Safety Rules

Direction is stored as (dx, dy). The _is_reverse_direction() helper checks whether a new direction is exactly opposite of current direction. If KEY_REPEAT_SAFETY is enabled in settings, set_direction() ignores instant 180-degree turns.

This mirrors expected Snake game behavior and prevents accidental self-collision from rapid opposite key presses.

6. Building a Scaffold First

This section intentionally stops before movement and collision methods are finished. Building a strong scaffold first helps students test core structure before adding more complex behavior.

Code Students Will Type (snake.py)

Type this code by hand so you understand each part of the class design.

Code image: s03-code

Detailed Code Review & Key Concepts

__init__ and Body Construction

  • The constructor creates an empty deque and stores starting direction.
  • It builds the initial snake by appending (x - i, y) so the head is first and the body trails left.
  • _grow_pending is initialized now so growth logic can be added safely later.

Properties as Public Interface

  • head gives direct access to the front segment.
  • body returns a tuple copy, protecting internal mutable state.
  • direction provides current movement vector.

This design supports safe collaboration between classes (for example, Game and Food can read snake state without mutating internals).

Direction Control Methods

  • set_direction() applies the new direction unless it would be an immediate reverse while safety is on.
  • _is_reverse_direction() isolates the reverse-check logic for readability and reuse.

Occupancy Helper

  • occupies(cell) checks whether a coordinate is part of the snake body.
  • This will be used by food spawning and collision logic later.

Test File (s03_test.py)

Use this test file to verify your class scaffold before adding movement methods.

Code image: s03-test

This test file checks the class scaffold in focused steps: - test_init_builds_expected_body_and_direction() verifies constructor setup. - test_body_property_returns_readable_snapshot() confirms body is safely exposed as a tuple snapshot. - test_set_direction_blocks_reverse_when_safety_enabled() checks the anti-reverse rule. - test_reverse_direction_helper() validates the helper method logic. - test_occupies() confirms body membership checks.

Running these tests now ensures the class structure is correct before movement and collision methods are added in Section 04.