🎯Calibrate
1Fill-in
2Debug
3Extend
4Create
🧠Concept
📓Reflect
👤 Your Details REQUIRED — fill in before you begin (★ = required)
🎯 Before You Begin Calibration Check 2 questions + 1 reflection — unlocks Tier 1
Think about how a list models the snake body, how adding/removing elements makes it grow or move, and how checking head-versus-food works.
1 10 5
Tier 1 Fill in the Blanks Complete the code skeleton — 5 blanks

Complete the snake body update logic. Fill each blank so the snake moves, eats food, grows, and scores correctly.

import random

snake = [(10,7),(9,7),(8,7)]   # head at index 0
food  = (random.randint(0,GRID_COLS-1), random.randint(0,GRID_ROWS-1))
score = 0

# --- compute new head ---
hx, hy = snake[▢1]
if direction == "RIGHT": hx += 1
elif direction == "LEFT":  hx -= 1
elif direction == "UP":    hy -= 1
elif direction == "DOWN":  hy += 1
new_head = (hx, hy)

# --- eat check ---
ate_food = (new_head == ▢2)

# --- update body ---
snake.▢3(0, new_head)
if not ate_food:
    snake.▢4()

# --- score & respawn food ---
if ate_food:
    score ▢5= 1
    food = (random.randint(0,GRID_COLS-1), random.randint(0,GRID_ROWS-1))
1.Blank 1: _
2.Blank 2: f___
3.Blank 3: i_____
4.Blank 4: p__
5.Blank 5: _
Tier 2 Find & Fix the Bugs 3 bugs to correct

The snake body code below has 3 bugs. Type the corrected line for each.

snake = [(10,7),(9,7),(8,7)]
food  = (5, 5)
score = 0

hx, hy = snake[0]
if direction == "RIGHT": hx += 1
new_head = (hx, hy)

ate_food = (new_head == food)
snake.append(new_head)     # Bug 1 – wrong end
if ate_food:
    snake.pop(0)           # Bug 2 – pops from wrong end; also should only pop when NOT eating
score += 1                 # Bug 3 – score always increments

Bug 1

Buggy line:

snake.append(new_head)

Your fix:

Hint: The new head goes at the FRONT (index 0) of the list, not the back.

Bug 2

Buggy line:

if ate_food: snake.pop(0)

Your fix:

Hint: Remove the TAIL only when NOT eating, and pop() removes the last element (the tail), not pop(0).

Bug 3

Buggy line:

score += 1 # (outside ate_food block)

Your fix:

Hint: Score should only increase when the snake actually eats — wrap it in the ate_food check.

Reflection 2 Mid-Point Check-In
Tier 3 Extend the Code Add the feature described below

Add **wall collision detection**: if the new head is outside the grid boundaries (hx < 0, hx >= GRID_COLS, hy < 0, hy >= GRID_ROWS), set `running = False` to end the game.

# After computing new_head, before updating body:
hx, hy = new_head

# YOUR CODE: check if new_head is outside the grid.
# If it is, set running = False and skip the body update.

ate_food = (new_head == food)
snake.insert(0, new_head)
if not ate_food:
    snake.pop()
Tier 4 Create from Scratch Open-ended challenge

**Challenge:** Spawn food that avoids the snake's current body. Write a `spawn_food(snake)` function that loops until it finds a position not in the snake list, then call it whenever food is eaten. Paste the full function and the updated eat block.

🧠 Concept Check Test Your Understanding 5 quick questions — required before the Reflective Journal 🔒

Answer all 5 questions, then the Reflective Journal will unlock.

1. food_x = random.randint(0, GRID_W-1) * CELL_SIZE — why multiply by CELL_SIZE?

2. What event triggers spawning a new food position?

3. Self-collision means:

4. pygame.draw.rect(win, GREEN, [x, y, w, h]) draws:

5. Which stores a food position correctly as grid coordinates?

📓 Reflective Journal 5 prompts — required before Step 4 is marked complete 🔒

Answer each prompt thoughtfully. There are no right or wrong answers — this is your own reflection.

🎯 Post-Activity Check-In After Completing All Tiers Complete after the Reflective Journal to finish this step 🔒
1. How confident do you feel about this step’s concepts now? (1 = not confident, 10 = very confident)
1 10 5
2. Your Tier 1 first-attempt score (auto-filled)
%