🎯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 what the modulo operator (%) does to a number at the grid edge. What value do you get when you go one step past the last column or row?
1 10 5
Tier 1 Fill in the Blanks Complete the code skeleton — 6 blanks

Complete the wrap-around movement. Fill each blank so the snake teleports from one edge to the opposite.

# direction -> (dx, dy) lookup
dx, dy = ▢1[direction]

hx, hy = snake[0]
hx = (hx + dx) % ▢2   # wraps left ↔ right
hy = (hy + dy) % ▢3   # wraps top  ↔ bottom
new_head = (hx, hy)

# Trace examples (GRID_COLS=20, GRID_ROWS=15):
# hx=19, moving RIGHT: (19+1) % 20 = ▢4   (wraps to left edge)
# hx=0,  moving LEFT:  ( 0-1) % 20 = ▢5  (wraps to right edge)
# hy=0,  moving UP:    ( 0-1) % 15 = ▢6  (wraps to bottom)
1.Blank 1: "___________________________________________________
2.Blank 2: G________
3.Blank 3: G________
4.Blank 4: _
5.Blank 5: 1_
6.Blank 6: 1_
Tier 2 Find & Fix the Bugs 3 bugs to correct

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

dx, dy = {"RIGHT":(1,0),"LEFT":(-1,0),"UP":(0,-1),"DOWN":(0,1)}[direction]
hx, hy = snake[0]

hx = (hx + dx) % GRID_ROWS    # Bug 1 – wrong constant
hy = (hy + dy) % GRID_ROWS

# Wall-death mode:
WALL_DEATH = True
if WALL_DEATH:
    alive = (0 <= hx < GRID_COLS) or (0 <= hy < GRID_ROWS)  # Bug 2 – wrong operator
    if not alive:
        running == False   # Bug 3 – comparison not assignment

Bug 1

Buggy line:

hx = (hx + dx) % GRID_ROWS

Your fix:

Hint: The x-axis (columns) wraps at GRID_COLS, not GRID_ROWS.

Bug 2

Buggy line:

alive = (0 <= hx < GRID_COLS) or (0 <= hy < GRID_ROWS)

Your fix:

Hint: Both coordinates must be in bounds simultaneously — use `and`, not `or`.

Bug 3

Buggy line:

running == False

Your fix:

Hint: `==` is a comparison that produces True/False but does nothing. `=` is the assignment that actually changes the variable.

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

Implement a `move_head(hx, hy, direction, wall_death)` function that returns `(new_hx, new_hy, alive)`. When `wall_death=True`, use bounds checking; when `False`, use modulo wrap.

def move_head(hx, hy, direction, wall_death=False):
    dx, dy = {"RIGHT":(1,0),"LEFT":(-1,0),"UP":(0,-1),"DOWN":(0,1)}[direction]
    # YOUR CODE:
    # If wall_death: compute new position, set alive = in-bounds check
    # Else:          use modulo wrap, alive = True
    pass  # replace with your implementation
Tier 4 Create from Scratch Open-ended challenge

**Challenge:** Add a **WALL_DEATH toggle** controlled by pressing the W key during gameplay. Display the current mode ("Wrap" or "Wall") in the corner. Paste your updated code.

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

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

1. def draw_snake(body): — what is body in this line?

2. What does a function return when it has no return statement?

3. Why call draw_snake(body) instead of pasting the drawing code everywhere?

4. What is variable scope?

5. def is_collision(head, body): return head in body — what type of value does this return?

📓 Reflective Journal 5 prompts — required before Step 6 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)
%