Intermediate — Day 3

Game Loop & Wall Collision

Day Schedule
Online
TimeActivity
10:00Game Loop Review
Walk through the while True structure line by line
10:10Wall Detection
xcor(), ycor(), halfSize boundary check
10:25reset_game()
Function to restore head to center; reset heading too
10:35Breakout Groups
Guided coding: full game loop + wall collision
11:00Break
11:10Breakout Groups
Guided coding continued
12:20Reminders
In-Person
TimeActivity
8:00Warm-Up
Review Day 2: test arrow keys for everyone
8:20Game Loop Review
Walk through the while True structure line by line
8:35Wall Detection
xcor(), ycor(), halfSize boundary check
8:55reset_game()
Function to restore head to center; reset heading too
9:20Breakout Groups
Guided coding: full game loop + wall collision
9:40Break
9:50Breakout Groups
Guided coding continued
11:00Break
11:10Extra Activity
Add a countdown display before the game restarts after a collision
11:50Open Coding
Catch up or polish collision detection
12:20Reminders
Learning Objectives
  1. Detect wall collision using xcor() and ycor()
  2. Write a reset_game() function to restore game state
  3. Understand why the game loop never exits — it resets instead
  4. Use halfSize = 290 (not 300) as the playable boundary
# INSTRUCTOR — Day 3: While Loops & Boundaries (Intermediate)
# -----------------------------------------------
# TEACH: The game loop pattern: while True runs every frame.
# Each frame: update screen → move snake → check walls → sleep.
# Boundary detection: xcor() and ycor() return the head's current position.
# If outside bounds, call reset_game() — the game never exits, it just resets.
#
# TEACH: halfSize = 300 means the playable area goes from -300 to +300.
# We use 290 in practice (not 300) so the snake visually stays inside the border.

import turtle
import time

screen = turtle.Screen()
screen.bgcolor("black")
screen.setup(width=600, height=600)
screen.tracer(0)

head = turtle.Turtle()
head.shape("square")
head.color("white")
head.penup()
head.goto(0, 0)

halfSize = 290  # TEACH: boundary is 10px inside the screen edge

def reset_game():
    # TEACH: reset_game restores the snake to its starting state — no exit needed
    head.goto(0, 0)
    head.setheading(0)

# TEACH: walk through the while True loop line by line before students run it
while True:
    screen.update()     # step 1: redraw the screen
    head.forward(20)    # step 2: move snake one step

    # step 3: check all four walls
    if (head.xcor() > halfSize or head.xcor() < -halfSize or
            head.ycor() > halfSize or head.ycor() < -halfSize):
        print("Hit the wall!")  # TEACH: print helps debug — remove later
        reset_game()

    time.sleep(0.1)     # step 4: pause (controls speed)

# TEACH: ask — what does 'or' mean here?
# The snake hits a wall if it goes too far left OR right OR up OR down.
# Any one of these four is enough to trigger reset.
# INSTRUCTOR — Day 3: Project: Snake: Game Loop & Wall Collision (Intermediate)
# -----------------------------------------------
# TEACH: Cumulative from Day 2. Students add the full game loop and reset_game().
# Check: snake moves, arrow keys work, wall collision resets to center.
# Common issue: snake moves but wall doesn't reset. Likely: wrong halfSize, or
# the condition uses > 300 but screen is only 600px (so ±300 is the edge, not 290).

import turtle
import time

screen = turtle.Screen()
screen.title("Snake Game")
screen.bgcolor("black")
screen.setup(width=600, height=600)
screen.tracer(0)

head = turtle.Turtle()
head.shape("square")
head.color("white")
head.penup()
head.goto(0, 0)

def go_up():
    if head.heading() != 270:
        head.setheading(90)

def go_down():
    if head.heading() != 90:
        head.setheading(270)

def go_left():
    if head.heading() != 0:
        head.setheading(180)

def go_right():
    if head.heading() != 180:
        head.setheading(0)

screen.listen()
screen.onkeypress(go_up,    "Up")
screen.onkeypress(go_down,  "Down")
screen.onkeypress(go_left,  "Left")
screen.onkeypress(go_right, "Right")

halfSize = 290

# TEACH: reset_game resets head position and direction. No score yet — that's Day 4/5.
def reset_game():
    head.goto(0, 0)
    head.setheading(0)

# TEACH: this is the full game loop — every future day adds into this while True block
while True:
    screen.update()
    head.forward(20)

    if (head.xcor() > halfSize or head.xcor() < -halfSize or
            head.ycor() > halfSize or head.ycor() < -halfSize):
        reset_game()

    time.sleep(0.1)
# INSTRUCTOR — Day 3: Extra Activity: Countdown Timer (Intermediate)
# -----------------------------------------------
# TEACH: Standalone exercise using while loop with a counter.
# Reinforces while condition, loop body modification, and time.sleep().
# Three blanks: starting value, stop condition, decrement.
# Students who get the challenge should use an if check inside the loop.

import time

countdown = 10      # starting value

while countdown > 0:            # stop when countdown reaches 0
    if countdown == 1:          # TEACH challenge: special case for final second
        print("FINAL SECOND!")
    else:
        print("Time left: " + str(countdown))
    time.sleep(1)
    countdown = countdown - 1   # decrement

print("Time's up!")

# TEACH: ask — what happens if we write `while countdown >= 0`?
# The loop runs one extra time (prints "Time left: 0") before stopping.
# Details like this matter in games for correct behavior.