← Teacher guide

Catch the turtle

The final challenge. Students build a game in three milestones, each with less help, using everything from the course; the turtle hops along a path and players catch it before it hides.

Python functions and events · Final challenge: Catch the turtle · about 60 minutes · Open the student lesson

Classroom resources

Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.

Students will be able to

Timing

Predict, Run and Investigate 15 min · Milestone 1 10 min · Milestone 2 15 min · Milestone 3 15 min · Path or random 5 min

Before class

Play the finished game (the Milestone 3 solution below) for a minute, then read the three milestone starters. Milestone 1 gives most of the code, milestone 2 an outline, milestone 3 only the goals: that fading support is deliberate. The two new words are True and False: a variable like showing remembers whether the turtle is on screen right now. Finishing this lesson and Power-ups marks the course "Challenge complete".

Running the lesson

  1. Predict and Investigate: the path is two lists (xs and ys) and place says where we are. % wraps place back to 0 at the end of a lap.
  2. The bug task is the missing global line from Events: Python stops on score = score + 1 with UnboundLocalError. Every milestone needs global in each function that changes score, showing or time_left, so point back to it when a student meets this error.
  3. Milestone 1: the catch is the hit test from Build a button, with the box centred on the turtle (tx - 20, ty - 20).
  4. Milestone 2: showing is True while the turtle is visible. Clicks only count when showing is True, and a turtle that hides uncaught is a miss.
  5. Milestone 3: students work from the five goals in the comment. Encourage one goal at a time, running after each.
  6. Path or random: let students play both. A path can be predicted; random spots can only be reacted to.

The hard part (on purpose)

Every variable a function changes needs global, and % wraps the path. When the score doesn't change, ask which variables the function changes.

When students get stuck

What you will seeA question to askThe fix
The score never changes, or an error says a name has no value.Which variables does this function change? Are they all in its global line?Every variable a function changes must be listed after global at the top of that function.
Clicking right on the turtle does not score.Where does the box around the turtle start?The box starts at (tx - 20, ty - 20) and is 40 by 40, so it is centred on the turtle.
After pressing Start twice quickly, the turtle hops twice as fast.How many hop loops might be running?Each Start begins a new hop loop. Only start one when playing is False (the solution checks this).

Answers to the checks

  1. Predict: The turtle starts at place 0. Where is it after its fourth hop?
    Bottom right (120, -50): the fourth hop uses place 3, the fourth number in each list.
  2. Trace the path: Fill in place after each hop. The lists have 6 spots.
    2, 0, 0
    (5 + 1) % 6 is 0, so after the sixth hop place goes back to the start of the lists.
  3. Change the path: You want the turtle to visit a seventh spot. What do you change?
    Add one number to xs and one to ys
    Each spot is one x and one y at the same place in the two lists. len(xs) already counts the new spot.
  4. Spot the bug: Every click should add a point, but the first click stops with an error. Click the line where it goes wrong.
    line 7
    Without global score, the line score = score + 1 makes a new score inside add_point and tries to read it before it has a value (UnboundLocalError). Add global score as the first line of the function so it changes the score made outside. Your game needs the same line in every function that changes score.
  5. Path or random?: Why can a good player beat the turtle on a path, but not at random?
    On a path you can predict the next spot and move there first
    A path is a pattern, and patterns can be predicted. Random spots can only be reacted to.

Solutions

One possible solution for each task. Other correct programs are fine.

Milestone 1: catch it

from turtle import *
from ui import inside

speed(0)
penup()

xs = [-120, 0, 120, 120, 0, -120]
ys = [60, 110, 60, -50, -100, -50]
place = 0
tx = 0
ty = 0
score = 0


def hop():
    global place, tx, ty
    tx = xs[place]
    ty = ys[place]
    place = (place + 1) % len(xs)
    goto(tx, ty)
    ontimer(hop, 1000)


def show_score():
    clear()
    goto(-190, 160)
    write(score, False, "left", ("Arial", 20, "normal"))
    goto(tx, ty)


def clicked(x, y):
    global score
    if inside(x, y, tx - 20, ty - 20, 40, 40):
        score = score + 1
        show_score()


hop()
show_score()
onscreenclick(clicked)
listen()
mainloop()

Milestone 2: now you see it

from turtle import *
from ui import inside, draw_button

speed(0)
penup()
hideturtle()

xs = [-120, 0, 120, 120, 0, -120]
ys = [60, 110, 60, -50, -100, -50]
place = 0
tx = 0
ty = 0
score = 0
misses = 0
showing = False


def hop():
    global place, tx, ty, showing
    tx = xs[place]
    ty = ys[place]
    place = (place + 1) % len(xs)
    goto(tx, ty)
    showturtle()
    showing = True
    ontimer(hide, 700)
    ontimer(hop, 1000)


def hide():
    global showing, misses
    if showing:
        misses = misses + 1
        showing = False
        hideturtle()


def show_score():
    clear()
    goto(-190, 160)
    write(score, False, "left", ("Arial", 20, "normal"))
    goto(tx, ty)


def clicked(x, y):
    global score, showing
    if showing and inside(x, y, tx - 20, ty - 20, 40, 40):
        score = score + 1
        showing = False
        hideturtle()
        show_score()


hop()
show_score()
onscreenclick(clicked)
listen()
mainloop()

Milestone 3: game on

from turtle import *
from ui import inside, draw_button

speed(0)
penup()
hideturtle()

xs = [-120, 0, 120, 120, 0, -120]
ys = [60, 110, 60, -50, -100, -50]
place = 0
tx = 0
ty = 0
score = 0
misses = 0
showing = False
time_left = 30
playing = False


def draw_scene():
    clear()
    goto(-190, 160)
    write(score, False, "left", ("Arial", 20, "normal"))
    goto(150, 160)
    write(time_left, False, "left", ("Arial", 20, "normal"))
    if playing == False:
        draw_button(-60, -180, 120, 40, "Start")
    goto(tx, ty)


def hop():
    global place, tx, ty, showing
    if playing:
        tx = xs[place]
        ty = ys[place]
        place = (place + 1) % len(xs)
        goto(tx, ty)
        showturtle()
        showing = True
        ontimer(hide, 700)
        ontimer(hop, 1000)


def hide():
    global showing, misses
    if showing:
        misses = misses + 1
        showing = False
        hideturtle()


def tick():
    global time_left, playing
    if playing:
        time_left = time_left - 1
        if time_left == 0:
            playing = False
            hideturtle()
        else:
            ontimer(tick, 1000)
        draw_scene()


def start():
    global score, misses, time_left, playing, place
    score = 0
    misses = 0
    time_left = 30
    place = 0
    playing = True
    draw_scene()
    hop()
    ontimer(tick, 1000)


def clicked(x, y):
    global score, showing
    if playing and showing and inside(x, y, tx - 20, ty - 20, 40, 40):
        score = score + 1
        showing = False
        hideturtle()
        draw_scene()
    if playing == False and inside(x, y, -60, -180, 120, 40):
        start()


draw_scene()
onscreenclick(clicked)
listen()
mainloop()

Stretch and support

Stretch: Make the path draw a picture (each spot a corner of a shape) and reveal it with the pen down at game over.

Support: Pair students for Milestone 3, one reading the goals and the other typing, swapping after each goal.

Exit ticket

A catch game scores a click with if showing and inside(x, y):, where showing is True only while the turtle is on screen. Why check showing as well as inside?

So a click only scores while the turtle is visible. After it hides, clicking its old spot should not count.

What each step is for

Where it leads

Power-ups (next) adds lives, a status bar, a gold turtle and an upgrade. Then two optional lessons: Control panel (towards Gradio and web pages) and Game levels (towards MakeCode Arcade and microStudio). Creative option: students design their own path, such as their initials.