Advanced — Day 3
AI Extensions + Pong
Day Schedule
Online
| Time | Activity |
|---|---|
| 10:00 | AI Extensions Overview Walk through all 6 features (A–F); students pick 2–3 to add |
| 10:20 | Breakout Groups Add chosen AI features to snake |
| 11:00 | Break |
| 11:10 | Pong Introduction Screen, two paddles, ball — map each concept back to snake |
| 11:20 | Breakout Groups Build Pong |
| 12:20 | Reminders |
In-Person
| Time | Activity |
|---|---|
| 8:00 | AI Extensions Overview Walk through all 6 features (A–F); students pick 2–3 to add |
| 8:20 | Breakout Groups Add chosen AI features to snake |
| 9:40 | Break |
| 9:50 | Pong Introduction Screen, two paddles, ball — map each concept back to snake |
| 10:10 | Breakout Groups Build Pong |
| 11:00 | Break |
| 11:10 | Open Coding Polish snake extensions or continue Pong |
| 12:20 | Reminders |
Learning Objectives
- Add at least one AI extension (score, speed scaling, bad food, etc.)
- Build the basic Pong structure: two paddles and a bouncing ball
Snake with All AI Features (A–F)
# INSTRUCTOR — Day 3 (Morning): Extend Snake with AI (Advanced)
# -----------------------------------------------
# TEACH: Students use AI to add features to their completed snake game.
# This file shows the FULL snake game with all AI-added features implemented and labeled.
# Students will add DIFFERENT combinations depending on what they choose.
# Your role: help them write good prompts and verify they understand generated code.
#
# DEMO PROMPT FORMAT (show this before students work):
# "I have a Python snake game using the Turtle library. Here is my code: [paste].
# Add [feature]. The snake head is called 'head', the body list is 'bodysegments',
# and the game loop is a while True block. Keep the existing structure."
#
# FEATURES IMPLEMENTED IN THIS FILE (each labeled):
# A. Bad food (red) — resets game when eaten
# B. Powerup (blue) — removes last body segment when eaten
# C. Speed scaling — snake speeds up on each food eaten
# D. Random color change on eat
# E. Pause toggle on P key
# F. Score display with high score
import turtle
import time
import random
screen = turtle.Screen()
screen.title("Snake Game — Extended")
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)
food = turtle.Turtle()
food.shape("circle")
food.color("green")
food.penup()
food.goto(random.randint(-270, 270), random.randint(-270, 270))
# --- FEATURE A: Bad food ---
badfood = turtle.Turtle()
badfood.shape("circle")
badfood.color("red")
badfood.penup()
badfood.goto(random.randint(-270, 270), random.randint(-270, 270))
# --- FEATURE B: Powerup ---
powerup = turtle.Turtle()
powerup.shape("circle")
powerup.color("blue")
powerup.penup()
powerup.goto(random.randint(-270, 270), random.randint(-270, 270))
# --- FEATURE F: Score display ---
pen = turtle.Turtle()
pen.penup()
pen.hideturtle()
pen.color("white")
pen.goto(0, 270)
score = 0
high_score = 0
def update_score():
pen.clear()
pen.write("Score: " + str(score) + " Best: " + str(high_score),
align="center", font=("Courier", 18, "bold"))
update_score()
bodysegments = []
# --- FEATURE C: Speed scaling ---
currentspeed = 0.1
speedfactor = 0.95 # each eat multiplies delay by 0.95 (speeds up)
# --- FEATURE E: Pause toggle ---
paused = False
def toggle_pause():
global paused
paused = not paused
screen.onkeypress(toggle_pause, "p")
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
SNAKE_COLORS = ["white", "yellow", "cyan", "lime", "orange", "magenta"]
def reset_game():
global score, currentspeed, high_score
if score > high_score:
high_score = score
score = 0
currentspeed = 0.1
head.goto(0, 0)
head.setheading(0)
head.color("white") # FEATURE D: reset color on game reset
for seg in bodysegments:
seg.hideturtle()
bodysegments.clear()
update_score()
while True:
if paused: # FEATURE E: skip entire frame when paused
time.sleep(0.05)
continue
screen.update()
for i in range(len(bodysegments) - 1, 0, -1):
bodysegments[i].goto(bodysegments[i - 1].pos())
bodysegments[i].setheading(bodysegments[i - 1].heading())
if len(bodysegments) > 0:
bodysegments[0].goto(head.pos())
bodysegments[0].setheading(head.heading())
head.forward(20)
# Good food
if head.distance(food) < 20:
food.goto(random.randint(-270, 270), random.randint(-270, 270))
score += 1
currentspeed *= speedfactor # FEATURE C: speed up
head.color(random.choice(SNAKE_COLORS)) # FEATURE D: color change
new_seg = head.clone()
bodysegments.append(new_seg)
update_score()
# FEATURE A: Bad food
if head.distance(badfood) < 20:
badfood.goto(random.randint(-270, 270), random.randint(-270, 270))
reset_game()
# FEATURE B: Powerup
if head.distance(powerup) < 20:
powerup.goto(random.randint(-270, 270), random.randint(-270, 270))
if bodysegments:
bodysegments[-1].hideturtle() # remove last segment visually
bodysegments.pop() # remove from list
# Body collision
for seg in bodysegments:
if head.distance(seg) < 15:
reset_game()
break
# Wall collision
if (head.xcor() > halfSize or head.xcor() < -halfSize or
head.ycor() > halfSize or head.ycor() < -halfSize):
reset_game()
time.sleep(currentspeed)
Pong
# INSTRUCTOR — Day 3 (Afternoon): Start Pong (Advanced)
# -----------------------------------------------
# TEACH: Students switch to a new project after the morning session.
# Pong introduces: two player objects (paddles), a ball with velocity attributes,
# bouncing off walls by reversing dy, and simple collision detection.
# Key new idea: dx and dy are attributes attached directly to the ball turtle.
# This is a lightweight way to store per-object state without a class.
#
# By end of afternoon: screen set up, ball moving, top/bottom bounce working,
# paddle controls working. Scoring and win condition are for Day 4 (if they continue Pong).
import turtle
import time
screen = turtle.Screen()
screen.title("Pong")
screen.bgcolor("black")
screen.setup(width=800, height=600)
screen.tracer(0)
# --- Ball ---
ball = turtle.Turtle()
ball.shape("circle")
ball.color("white")
ball.penup()
ball.goto(0, 0)
ball.dx = 3 # TEACH: dx/dy are custom attributes we attach to the turtle object
ball.dy = 3 # dx = horizontal speed per frame; dy = vertical speed per frame
# --- Paddles ---
paddle_a = turtle.Turtle() # left paddle
paddle_a.shape("square")
paddle_a.shapesize(stretch_wid=5, stretch_len=1) # TEACH: shapesize stretches the square into a rectangle
paddle_a.color("white")
paddle_a.penup()
paddle_a.goto(-350, 0)
paddle_b = turtle.Turtle() # right paddle
paddle_b.shape("square")
paddle_b.shapesize(stretch_wid=5, stretch_len=1)
paddle_b.color("white")
paddle_b.penup()
paddle_b.goto(350, 0)
# --- Paddle movement ---
def paddle_a_up():
y = paddle_a.ycor()
if y < 250: # TEACH: boundary check so paddle stays on screen
paddle_a.sety(y + 20)
def paddle_a_down():
y = paddle_a.ycor()
if y > -250:
paddle_a.sety(y - 20)
def paddle_b_up():
y = paddle_b.ycor()
if y < 250:
paddle_b.sety(y + 20)
def paddle_b_down():
y = paddle_b.ycor()
if y > -250:
paddle_b.sety(y - 20)
screen.listen()
screen.onkeypress(paddle_a_up, "w")
screen.onkeypress(paddle_a_down, "s")
screen.onkeypress(paddle_b_up, "Up")
screen.onkeypress(paddle_b_down, "Down")
# --- Score ---
score_a = 0
score_b = 0
pen = turtle.Turtle()
pen.penup()
pen.hideturtle()
pen.color("white")
pen.goto(0, 260)
def update_score():
pen.clear()
pen.write(str(score_a) + " : " + str(score_b),
align="center", font=("Courier", 24, "bold"))
update_score()
while True:
screen.update()
# Move ball
ball.setx(ball.xcor() + ball.dx)
ball.sety(ball.ycor() + ball.dy)
# Top and bottom wall bounce
if ball.ycor() > 280 or ball.ycor() < -280:
ball.dy *= -1 # TEACH: reversing dy makes the ball bounce off horizontal walls
# Left and right wall — score and reset
if ball.xcor() > 390:
score_a += 1 # player A scores when ball passes right wall
update_score()
ball.goto(0, 0)
ball.dx *= -1 # TEACH: reverse direction after a point
if ball.xcor() < -390:
score_b += 1
update_score()
ball.goto(0, 0)
ball.dx *= -1
# Paddle collision — right paddle
if (ball.xcor() > 330 and ball.xcor() < 360 and
ball.ycor() < paddle_b.ycor() + 50 and
ball.ycor() > paddle_b.ycor() - 50):
ball.setx(330) # TEACH: snap ball back so it doesn't get stuck inside paddle
ball.dx *= -1
# Paddle collision — left paddle
if (ball.xcor() < -330 and ball.xcor() > -360 and
ball.ycor() < paddle_a.ycor() + 50 and
ball.ycor() > paddle_a.ycor() - 50):
ball.setx(-330)
ball.dx *= -1
time.sleep(0.01) # TEACH: Pong is faster than snake — smaller sleep value