MIL-003: Check against day 21 #25

Merged
Tirsvad merged 1 commits from mil-003-check-against-day-21 into main 2026-10-08 12:49:43 +02:00
Owner

MIL-003: Check against day 21

This is the last gateway of the plan (docs/project-plan.md). It compares the adopted game with the five day-21 lectures, corrects the code where it differs, and finishes the README. The base was written against assumed day-21 numbers; the lecture summaries now confirm them.

Result: nothing differs, so no source file changes. The only file in this pull request is README.md.

What is in the pull request

  • README.md: the Status block now says the game is finished and checked against the day-21 lectures, and a table shows where each lesson lives in the code, so that S02 can compare it with their own solution (one commit, Task: MIL-003#7).
  • The comparison of tasks 1 to 6 and the check of task 8 are recorded in this description. They need no file.

Comparison with the day-21 lectures

The lecture summaries are the specification (the request holds summaries only, not the video). Values were read from the running code, and the behaviour from the recorded calls of the real Food and Scoreboard classes over a fake Turtle.

# Lecture Lecture summary says Code has Result Where, and proven by
1 1. Inheritance and slicing One class inherits the attributes and methods of another; lists are sliced class Food(Turtle), class Scoreboard(Turtle), both calling super().__init__(); the tail check loops over the slice segments[1:] Same food.py:34, scoreboard.py:23, snake.py:218; test_food_inherits_from_turtle_and_calls_the_base_class_first, test_scoreboard_inherits_from_turtle
2 2. Food A blue circle of 10 by 10 pixels Shape circle, colour blue, stretch 0.5 of the default 20 pixel turtle, which is 10 by 10 pixels Same constants.py:57,60,63; test_food_is_a_blue_half_size_circle_with_the_pen_up_and_no_animation
3 2. Food The random place comes from the random module and is never at the edge of the screen random.randint(-280, 280) for x and y; the screen reaches 300, so the food is never within 20 pixels of the edge Same food.py:31, WALL_LIMIT at constants.py:71; test_random_coordinate_asks_for_a_number_from_wall_to_wall, test_random_places_are_always_inside_the_walls
4 2. Food The head and the food collide when distance is less than 15 head.distance(food.position()) < FOOD_COLLISION_DISTANCE, with the constant 15; strictly less than Same constants.py:74, main.py:140; test_the_snake_eats_food_closer_than_the_eating_distance, test_the_snake_does_not_eat_food_at_or_beyond_the_eating_distance
5 2. Food refresh gives the food new random coordinates, when it is made and at every collision Food.__init__ calls self.refresh(); eat_food_if_close calls food.refresh() Same food.py:45,47, main.py:140; test_food_starts_at_a_random_place, test_refresh_moves_the_food_to_a_new_random_place, test_main_lets_the_snake_eat_the_food_that_lies_on_its_way
6 3. Scoreboard Scoreboard inherits from Turtle; the score starts at 0; the text is written with alignment and font; the turtle is hidden; colour and place are set Recorded calls of the real class: color('white'), hideturtle(), goto((0, 270)), write('Score: 0', align='center', font=('Arial', 24, 'normal')) Same scoreboard.py:23-35, constants.py:77-89; test_scoreboard_is_white_hidden_and_at_the_top_centre, test_scoreboard_starts_by_writing_score_0_centred_in_arial_24
7 3. Scoreboard increase_score adds 1; the old text is cleared before the new text is written; update_scoreboard does both; alignment and font are constants Recorded calls after two foods: clear(), write('Score: 1', ...), clear(), write('Score: 2', ...); the constants are named SCOREBOARD_ALIGNMENT and SCOREBOARD_FONT (the summary suggests constants but does not fix their names) Same scoreboard.py:37-49; test_increase_score_wipes_the_old_text_and_writes_the_new_score, test_every_food_adds_one_to_the_score
8 4. Wall The wall is at 280 and -280 on both axes; passing it makes game_is_on false; GAME OVER is shown in the middle and the score stays visible abs(x) > 280 or abs(y) > 280; game_is_on is set to false in the main flow; Scoreboard.game_over writes GAME OVER centred at (0, 0) and does not clear the score Same snake.py:198, main.py:156,206, scoreboard.py:51; test_the_head_has_passed_the_wall_beyond_the_limit_on_any_side, test_the_head_has_not_passed_the_wall_at_or_inside_the_limit, test_main_ends_the_game_at_the_wall_shows_game_over_and_waits_for_a_click, test_game_over_leaves_the_score_on_the_screen
9 5. Tail Eating adds a segment: extend calls add_segment with the position of the last segment self.add_segment(self.segments[-1].position()) Same snake.py:161,176,182; test_extend_adds_one_segment_where_the_last_segment_is, test_extend_twice_adds_two_segments
10 5. Tail The head touches the tail when it is closer than 10 pixels to a segment; the head is skipped so it does not collide with itself head.distance(segment.position()) < TAIL_COLLISION_DISTANCE (10) for every segment in segments[1:] Same snake.py:207-219, constants.py:92; test_the_head_touches_the_tail_closer_than_the_touch_distance, test_the_head_does_not_touch_the_tail_at_or_beyond_the_touch_distance, test_a_new_snake_does_not_touch_its_tail, test_a_snake_with_only_a_head_has_no_tail_to_touch

All 24 tests named above exist and pass (42 tests match those names).

Checks run (Windows PowerShell)

  • A fresh git clone over HTTPS of merged main (f2c5d61) into an empty folder, then the README's set-up: python -m venv .venv, python -m pip install --upgrade pip, python -m pip install -e ".[dev]" (exit 0 each), pytest 128 passed, ruff check, ruff format --check, mypy clean, doxygen Doxyfile 0 warnings with HTML written. The README changes in this pull request are text only; the commands are unchanged.
  • The repository page on the git host still has the description (265 characters, unchanged from MIL-001) and 12 topics. The GitHub copy also shows the same description and topics; they were not set by this project.
  • .env is untracked and its token values occur in no tracked file.

MIL-003 Go/No-Go criteria

# Criterion Result
1 The comparison is complete Pass: one row for each of the ten lecture points
2 Every difference is resolved Pass: no row differs
3 The lessons of day 21 are visible Pass: Food and Scoreboard are subclasses of Turtle and call super().__init__(); hits_tail loops over segments[1:]
4 Food is shown Open: S01's manual run. Values and tests pass
5 The snake eats Open: S01's manual run. Tests pass
6 The scoreboard shows the score Open: S01's manual run. Recorded calls show Score: 0, then Score: 1 after a clear
7 The wall ends the game Open: S01's manual run. Tests pass for each side and just inside
8 The tail ends the game Open: S01's manual run. Tests pass for touching, not touching, no tail and right after eating
9 A click closes the window Partly open. Closing the window during play ended with exit code 0 and no error output (observed in MIL-002); the click after game over is covered by tests only
10 Tests and checks are green Pass
11 The README is finished Pass
12 The repository page is complete Pass
13 The game matches the lecture Open: S01 compares with the video
14 The code is reviewed Pass: no source file changed, so no new code review is needed

For the reviewer

  • One play session closes the open rows. Please play the game in Windows PowerShell with the .venv active (python -m snake_game) and check criteria 4 to 9 here, and criterion 5 of MIL-002 (issue #14). The assistant has not seen the game rendered.
  • Criterion 13 is yours. The assistant had only the text summaries. Please run the game next to the lecture video and write any difference below or in a comment. Issue #22 is left open for that.
  • The Project Plan still lists the GitHub copy as an open issue; it is now stale because the copy has a description and topics. It is not changed here, since a change to the plan needs your acceptance.

Closes #15
Closes #16
Closes #17
Closes #18
Closes #19
Closes #20
Closes #21
Refs #22

## MIL-003: Check against day 21 This is the last gateway of the plan (`docs/project-plan.md`). It compares the adopted game with the five day-21 lectures, corrects the code where it differs, and finishes the README. The base was written against assumed day-21 numbers; the lecture summaries now confirm them. **Result: nothing differs, so no source file changes.** The only file in this pull request is `README.md`. ### What is in the pull request - `README.md`: the Status block now says the game is finished and checked against the day-21 lectures, and a table shows where each lesson lives in the code, so that S02 can compare it with their own solution (one commit, `Task: MIL-003#7`). - The comparison of tasks 1 to 6 and the check of task 8 are recorded in this description. They need no file. ### Comparison with the day-21 lectures The lecture summaries are the specification (the request holds summaries only, not the video). Values were read from the running code, and the behaviour from the recorded calls of the real `Food` and `Scoreboard` classes over a fake `Turtle`. | # | Lecture | Lecture summary says | Code has | Result | Where, and proven by | | --- | --- | --- | --- | --- | --- | | 1 | 1. Inheritance and slicing | One class inherits the attributes and methods of another; lists are sliced | `class Food(Turtle)`, `class Scoreboard(Turtle)`, both calling `super().__init__()`; the tail check loops over the slice `segments[1:]` | Same | `food.py:34`, `scoreboard.py:23`, `snake.py:218`; `test_food_inherits_from_turtle_and_calls_the_base_class_first`, `test_scoreboard_inherits_from_turtle` | | 2 | 2. Food | A blue circle of 10 by 10 pixels | Shape `circle`, colour `blue`, stretch 0.5 of the default 20 pixel turtle, which is 10 by 10 pixels | Same | `constants.py:57,60,63`; `test_food_is_a_blue_half_size_circle_with_the_pen_up_and_no_animation` | | 3 | 2. Food | The random place comes from the `random` module and is never at the edge of the screen | `random.randint(-280, 280)` for x and y; the screen reaches 300, so the food is never within 20 pixels of the edge | Same | `food.py:31`, `WALL_LIMIT` at `constants.py:71`; `test_random_coordinate_asks_for_a_number_from_wall_to_wall`, `test_random_places_are_always_inside_the_walls` | | 4 | 2. Food | The head and the food collide when `distance` is less than 15 | `head.distance(food.position()) < FOOD_COLLISION_DISTANCE`, with the constant 15; strictly less than | Same | `constants.py:74`, `main.py:140`; `test_the_snake_eats_food_closer_than_the_eating_distance`, `test_the_snake_does_not_eat_food_at_or_beyond_the_eating_distance` | | 5 | 2. Food | `refresh` gives the food new random coordinates, when it is made and at every collision | `Food.__init__` calls `self.refresh()`; `eat_food_if_close` calls `food.refresh()` | Same | `food.py:45,47`, `main.py:140`; `test_food_starts_at_a_random_place`, `test_refresh_moves_the_food_to_a_new_random_place`, `test_main_lets_the_snake_eat_the_food_that_lies_on_its_way` | | 6 | 3. Scoreboard | `Scoreboard` inherits from `Turtle`; the score starts at 0; the text is written with alignment and font; the turtle is hidden; colour and place are set | Recorded calls of the real class: `color('white')`, `hideturtle()`, `goto((0, 270))`, `write('Score: 0', align='center', font=('Arial', 24, 'normal'))` | Same | `scoreboard.py:23-35`, `constants.py:77-89`; `test_scoreboard_is_white_hidden_and_at_the_top_centre`, `test_scoreboard_starts_by_writing_score_0_centred_in_arial_24` | | 7 | 3. Scoreboard | `increase_score` adds 1; the old text is cleared before the new text is written; `update_scoreboard` does both; alignment and font are constants | Recorded calls after two foods: `clear()`, `write('Score: 1', ...)`, `clear()`, `write('Score: 2', ...)`; the constants are named `SCOREBOARD_ALIGNMENT` and `SCOREBOARD_FONT` (the summary suggests constants but does not fix their names) | Same | `scoreboard.py:37-49`; `test_increase_score_wipes_the_old_text_and_writes_the_new_score`, `test_every_food_adds_one_to_the_score` | | 8 | 4. Wall | The wall is at 280 and -280 on both axes; passing it makes `game_is_on` false; GAME OVER is shown in the middle and the score stays visible | `abs(x) > 280 or abs(y) > 280`; `game_is_on` is set to false in the main flow; `Scoreboard.game_over` writes `GAME OVER` centred at (0, 0) and does not clear the score | Same | `snake.py:198`, `main.py:156,206`, `scoreboard.py:51`; `test_the_head_has_passed_the_wall_beyond_the_limit_on_any_side`, `test_the_head_has_not_passed_the_wall_at_or_inside_the_limit`, `test_main_ends_the_game_at_the_wall_shows_game_over_and_waits_for_a_click`, `test_game_over_leaves_the_score_on_the_screen` | | 9 | 5. Tail | Eating adds a segment: `extend` calls `add_segment` with the position of the last segment | `self.add_segment(self.segments[-1].position())` | Same | `snake.py:161,176,182`; `test_extend_adds_one_segment_where_the_last_segment_is`, `test_extend_twice_adds_two_segments` | | 10 | 5. Tail | The head touches the tail when it is closer than 10 pixels to a segment; the head is skipped so it does not collide with itself | `head.distance(segment.position()) < TAIL_COLLISION_DISTANCE` (10) for every `segment` in `segments[1:]` | Same | `snake.py:207-219`, `constants.py:92`; `test_the_head_touches_the_tail_closer_than_the_touch_distance`, `test_the_head_does_not_touch_the_tail_at_or_beyond_the_touch_distance`, `test_a_new_snake_does_not_touch_its_tail`, `test_a_snake_with_only_a_head_has_no_tail_to_touch` | All 24 tests named above exist and pass (42 tests match those names). ### Checks run (Windows PowerShell) - A fresh `git clone` over HTTPS of merged `main` (`f2c5d61`) into an empty folder, then the README's set-up: `python -m venv .venv`, `python -m pip install --upgrade pip`, `python -m pip install -e ".[dev]"` (exit 0 each), `pytest` 128 passed, `ruff check`, `ruff format --check`, `mypy` clean, `doxygen Doxyfile` 0 warnings with HTML written. The README changes in this pull request are text only; the commands are unchanged. - The repository page on the git host still has the description (265 characters, unchanged from MIL-001) and 12 topics. The GitHub copy also shows the same description and topics; they were not set by this project. - `.env` is untracked and its token values occur in no tracked file. ### MIL-003 Go/No-Go criteria | # | Criterion | Result | | --- | --- | --- | | 1 | The comparison is complete | Pass: one row for each of the ten lecture points | | 2 | Every difference is resolved | Pass: no row differs | | 3 | The lessons of day 21 are visible | Pass: `Food` and `Scoreboard` are subclasses of `Turtle` and call `super().__init__()`; `hits_tail` loops over `segments[1:]` | | 4 | Food is shown | **Open: S01's manual run.** Values and tests pass | | 5 | The snake eats | **Open: S01's manual run.** Tests pass | | 6 | The scoreboard shows the score | **Open: S01's manual run.** Recorded calls show `Score: 0`, then `Score: 1` after a clear | | 7 | The wall ends the game | **Open: S01's manual run.** Tests pass for each side and just inside | | 8 | The tail ends the game | **Open: S01's manual run.** Tests pass for touching, not touching, no tail and right after eating | | 9 | A click closes the window | **Partly open.** Closing the window during play ended with exit code 0 and no error output (observed in MIL-002); the click after game over is covered by tests only | | 10 | Tests and checks are green | Pass | | 11 | The README is finished | Pass | | 12 | The repository page is complete | Pass | | 13 | The game matches the lecture | **Open: S01 compares with the video** | | 14 | The code is reviewed | Pass: no source file changed, so no new code review is needed | ### For the reviewer - **One play session closes the open rows.** Please play the game in Windows PowerShell with the `.venv` active (`python -m snake_game`) and check criteria 4 to 9 here, and criterion 5 of MIL-002 (issue #14). The assistant has not seen the game rendered. - **Criterion 13 is yours.** The assistant had only the text summaries. Please run the game next to the lecture video and write any difference below or in a comment. Issue #22 is left open for that. - The Project Plan still lists the GitHub copy as an open issue; it is now stale because the copy has a description and topics. It is not changed here, since a change to the plan needs your acceptance. Closes #15 Closes #16 Closes #17 Closes #18 Closes #19 Closes #20 Closes #21 Refs #22
Tirsvad added this to the MIL-003: Check against day 21 milestone 2026-10-08 12:46:15 +02:00
Tirsvad added 1 commit 2026-10-08 12:46:16 +02:00
Finish the README for the Day 21 repository
CI / checks (push) Successful in 44s
CI / checks (pull_request) Successful in 44s
f3f69feb56
The Status block now says the game is finished and checked against the day-21 lectures, and a table shows where each lesson lives in the code (inheritance, collisions with the food, the scoreboard, the wall, the tail and slicing). No source file changes: the comparison with the lectures found no difference.

Task: MIL-003#7
Closes #21
Tirsvad merged commit d8542c34f1 into main 2026-10-08 12:49:43 +02:00
Tirsvad deleted branch mil-003-check-against-day-21 2026-10-08 12:58:12 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Tirsvad-Udemy-100-days-of-code/021-snake-game#25