Project Overview
In this project, you’ll create a Simon Says-style memory game where players must remember and repeat sequences of colored patterns. This is perfect for creating an escape room puzzle that simulates cracking a high-tech security system!
What you’ll learn:
- How to manage lists (arrays) to store sequences
- Creating random sequences
- Making visual animations with turtle graphics
- Handling user keyboard input
- Building progressive difficulty systems
Part 1: Setting Up Your Game Interface
Learning Goal
Before we can make a game, we need to create the visual elements that players will see and interact with. Think of this like setting up a stage before a play!
Example: Creating and Positioning Turtles
Let’s start by learning how to create and position turtle objects. Here’s a simple example that creates colored circles on the screen:
import turtle
# Create the screen (like creating a canvas to draw on)
screen = turtle.Screen()
screen.bgcolor("navy") # Set background color
screen.setup(width=400, height=300) # Set screen size
# Create our first turtle object
circle1 = turtle.Turtle()
circle1.shape("circle") # Make it look like a circle
circle1.color("red") # Make it red
circle1.penup() # Don't draw lines when moving
circle1.goto(-50, 0) # Move to position x=-50, y=0
# Create a second turtle object
circle2 = turtle.Turtle()
circle2.shape("circle")
circle2.color("blue")
circle2.penup()
circle2.goto(50, 0) # Move to position x=50, y=0
# Keep the window open
screen.mainloop()
Key Concepts Explained:
turtle.Turtle()creates a new turtle object (like creating a new character).shape()changes what the turtle looks like.color()changes the turtle’s color.penup()means “don’t draw lines when moving”.goto(x, y)moves the turtle to specific coordinates (x is left/right, y is up/down)screen.mainloop()keeps the window open so you can see your creation
Your Task: Create the Memory Game Interface
Now it’s your turn! Create a memory game interface with:
- Four colored square buttons arranged in a 2×2 grid
- Text displays for showing messages to the player
Requirements:
- Use
"square"shape for your buttons - Colors should be: red, blue, green, yellow
- Position the buttons like this:
RED BLUE (−100,50) (100,50) GREEN YELLOW (−100,−50) (100,−50)
Starter Code Framework:
import turtle
import random
# Set up the screen
wn = turtle.Screen()
wn.bgcolor("black")
wn.setup(width=600, height=450)
# Create your button turtles here
# Remember: shape("square"), penup(), goto(x,y), color()
# Create text display turtles here
# Hint: Use hideturtle() to make text-only turtles invisible
wn.mainloop()
Challenge: Try creating a title turtle that displays “MEMORY SEQUENCE DEVICE” at the top of the screen!
Part 2: Working with Lists and Random Generation
Learning Goal
Games need to store and manage data. In our memory game, we need to create random sequences and store what the player inputs. Lists are perfect for this!
Example: Understanding Lists and Random Numbers
import random
# Creating and working with lists
my_colors = ["red", "blue", "green", "yellow"]
print("First color:", my_colors[0]) # Prints: red
print("Second color:", my_colors[1]) # Prints: blue
print("List length:", len(my_colors)) # Prints: 4
# Adding items to a list
sequence = [] # Start with empty list
sequence.append(2) # Add the number 2
sequence.append(0) # Add the number 0
print("My sequence:", sequence) # Prints: [2, 0]
# Generating random numbers
for i in range(5): # Do this 5 times
random_num = random.randint(0, 3) # Random number from 0 to 3
print("Random number:", random_num)
# Creating a random sequence
random_sequence = []
for i in range(4): # Create 4 random numbers
random_button = random.randint(0, 3)
random_sequence.append(random_button)
print("Random sequence:", random_sequence)
Key Concepts Explained:
- Lists store multiple items:
my_list = [item1, item2, item3] - Access items by position:
my_list[0]gets the first item len(my_list)tells you how many items are in the listmy_list.append(item)adds a new item to the endrandom.randint(0, 3)gives you a random number from 0 to 3for i in range(4):repeats something 4 times
Your Task: Create Sequence Management
Add these variables and functions to your memory game:
Required Variables:
# Game data storage
sequence = [] # Will store the pattern to remember
player_sequence = [] # Will store what player enters
current_level = 1 # What level the player is on
button_colors = ["red", "blue", "green", "yellow"]
Required Function: Create a function that generates a new random sequence. The sequence should get longer as levels increase:
- Level 1: 3 buttons
- Level 2: 4 buttons
- Level 3: 5 buttons
- etc.
Function Template:
def generate_new_sequence():
global sequence # This lets us modify the sequence variable
sequence = [] # Start with empty sequence
# Calculate how long this sequence should be
sequence_length = 2 + current_level
# Your code here: create sequence_length random numbers (0-3)
# and append them to the sequence list
Test Your Function:
# Test your function
current_level = 1
generate_new_sequence()
print("Level 1 sequence:", sequence)
current_level = 3
generate_new_sequence()
print("Level 3 sequence:", sequence)
Part 3: Animation and Visual Feedback
Learning Goal
Games need to show players what’s happening! We’ll learn how to make buttons “light up” and create timed animations.
Example: Color Changes and Timing
import turtle
# Set up
screen = turtle.Screen()
screen.bgcolor("black")
# Create a button
button = turtle.Turtle()
button.shape("square")
button.penup()
button.goto(0, 0)
button.color("red")
# Function to make button flash
def flash_button():
button.color("pink") # Change to bright color
screen.ontimer(reset_button, 500) # Reset after 500ms (0.5 seconds)
def reset_button():
button.color("red") # Change back to normal color
# Function to demonstrate the flash
def start_demo():
screen.ontimer(flash_button, 1000) # Flash after 1 second
# Set up keyboard control
screen.listen()
screen.onkey(start_demo, "space") # Press space to start demo
print("Press space to see the button flash!")
screen.mainloop()
Key Concepts Explained:
.color()instantly changes a turtle’s colorscreen.ontimer(function, milliseconds)calls a function after a delay- 1000 milliseconds = 1 second, 500 milliseconds = 0.5 seconds
screen.listen()tells the program to watch for keyboard inputscreen.onkey(function, "key")runs a function when a key is pressed
Example: Showing a Sequence Step by Step
# Example of showing items one at a time
demo_sequence = [0, 2, 1, 3] # Example sequence
current_position = 0
def show_next_item():
global current_position
if current_position < len(demo_sequence):
item = demo_sequence[current_position]
print(f"Showing item {current_position}: {item}")
current_position = current_position + 1
# Show next item after 1 second
screen.ontimer(show_next_item, 1000)
else:
print("Sequence finished!")
current_position = 0 # Reset for next time
Your Task: Create Button Animation System
Add these functions to your memory game:
Required Functions:
- Button Lighting Functions:
def light_up_button(button_index):
# Change button at button_index to its bright color
# Hint: Use your button_turtles list and bright_colors list
def reset_button(button_index):
# Change button back to its normal color
def reset_all_buttons():
# Reset all 4 buttons to normal colors
# Hint: Use a for loop with range(4)
Sequence Display Functions:
def show_sequence():
global sequence_position
sequence_position = 0 # Start at beginning
# Display message to player
status.clear()
status.write("Watch the sequence...", align="center", font=("Arial", 14, "normal"))
show_sequence_step() # Start showing the sequence
def show_sequence_step():
global sequence_position
if sequence_position < len(sequence):
# Light up the current button in the sequence
button_index = sequence[sequence_position]
light_up_button(button_index)
sequence_position = sequence_position + 1
wn.ontimer(reset_and_continue, 800) # Reset after 0.8 seconds
else:
# Sequence finished - start player input
start_player_input()
def reset_and_continue():
# Reset the previous button and continue with next
if sequence_position > 0:
prev_button = sequence[sequence_position - 1]
reset_button(prev_button)
wn.ontimer(show_sequence_step, 400) # Next button after 0.4 seconds
Challenge: Create bright color versions of your button colors and store them in a bright_colors list!
Part 4: Handling Player Input
Learning Goal
Now we need to detect when players press keys and check if they’re repeating the sequence correctly.
Example: Keyboard Input and Checking Lists
import turtle
# Set up
screen = turtle.Screen()
player_answer = [] # Store what player types
correct_answer = [1, 3, 2, 0] # What they should type
def key_pressed(number):
player_answer.append(number)
print(f"You pressed: {number}")
print(f"Your sequence so far: {player_answer}")
# Check if they've entered enough numbers
if len(player_answer) == len(correct_answer):
check_answer()
def check_answer():
print("\nChecking your answer...")
# Compare the two lists
if player_answer == correct_answer:
print("Correct! Well done!")
else:
print("Incorrect. Try again!")
player_answer.clear() # Empty the list to start over
# Set up keyboard controls
def press_1():
key_pressed(1)
def press_2():
key_pressed(2)
def press_3():
key_pressed(3)
def press_4():
key_pressed(4)
screen.listen()
screen.onkey(press_1, "1")
screen.onkey(press_2, "2")
screen.onkey(press_3, "3")
screen.onkey(press_4, "4")
print("Press keys 1, 2, 3, 4 to enter sequence: [1, 3, 2, 0]")
screen.mainloop()
Key Concepts Explained:
list.clear()empties a list completelylist1 == list2checks if two lists contain exactly the same items- We create separate functions for each key to avoid advanced programming concepts
- Each key press adds a number to our tracking list
Example: Checking Input Step by Step
# Instead of waiting for complete sequence, check each step
def check_step_by_step(player_input):
current_position = len(player_input) - 1 # Position of newest input
if player_input[current_position] == correct_answer[current_position]:
print(f"Step {current_position + 1} correct!")
# Check if sequence is complete
if len(player_input) == len(correct_answer):
print("Entire sequence correct!")
else:
print("Wrong! Starting over...")
player_input.clear()
Your Task: Add Player Input System
Add these components to your memory game:
Required Variables:
game_state = "waiting" # Can be "waiting", "showing", "input", "complete"
Required Functions:
- Input Management:
def start_player_input():
global game_state, player_sequence
game_state = "input"
player_sequence = [] # Clear previous attempts
# Show instructions to player
status.clear()
status.write("Repeat the sequence! Press 1,2,3,4 for buttons",
align="center", font=("Arial", 12, "normal"))
def player_press_button(button_number):
global player_sequence
if game_state == "input": # Only accept input during input phase
# Add button to player's sequence
player_sequence.append(button_number)
# Light up the button they pressed
light_up_button(button_number)
wn.ontimer(reset_pressed_button, 300)
# Check their progress
check_player_input()
Input Checking:
def check_player_input():
# Check if current input is correct so far
current_pos = len(player_sequence) - 1
if player_sequence[current_pos] == sequence[current_pos]:
# Correct so far!
if len(player_sequence) == len(sequence):
# Complete sequence correct!
level_completed()
else:
# Wrong button pressed
sequence_failed()
def reset_pressed_button():
# Reset the last button the player pressed
if len(player_sequence) > 0:
last_button = player_sequence[-1] # -1 gets the last item
reset_button(last_button)
Keyboard Setup:
# Create separate functions for each key (required for Trinket)
def press_button_1():
player_press_button(0) # Button 0 = red button
def press_button_2():
player_press_button(1) # Button 1 = blue button
def press_button_3():
player_press_button(2) # Button 2 = green button
def press_button_4():
player_press_button(3) # Button 3 = yellow button
# Set up keyboard controls
wn.listen()
wn.onkey(press_button_1, "1")
wn.onkey(press_button_2, "2")
wn.onkey(press_button_3, "3")
wn.onkey(press_button_4, "4")
Part 5: Game Logic and Level Progression
Learning Goal
Now we’ll add the “game” part – handling success, failure, and moving between levels!
Example: Simple Win/Lose Logic
import turtle
# Set up
screen = turtle.Screen()
message = turtle.Turtle()
message.hideturtle()
message.penup()
message.goto(0, 0)
score = 0
lives = 3
def player_wins():
global score
score = score + 1
message.clear()
message.color("green")
message.write(f"Success! Score: {score}", align="center", font=("Arial", 16, "bold"))
def player_loses():
global lives
lives = lives - 1
message.clear()
if lives > 0:
message.color("red")
message.write(f"Try again! Lives left: {lives}", align="center", font=("Arial", 16, "normal"))
else:
message.color("red")
message.write("Game Over!", align="center", font=("Arial", 20, "bold"))
def reset_game():
global score, lives
score = 0
lives = 3
message.clear()
message.color("white")
message.write("Game Reset - Press 'w' to win, 'l' to lose", align="center", font=("Arial", 12, "normal"))
# Test controls
screen.listen()
screen.onkey(player_wins, "w")
screen.onkey(player_loses, "l")
screen.onkey(reset_game, "r")
reset_game()
screen.mainloop()
Key Concepts Explained:
- Global variables let functions modify values that persist between function calls
- We can change text color with
.color()before writing .clear()erases previous text before showing new text
Example: Level Progression System
current_level = 1
max_levels = 5
def advance_level():
global current_level
if current_level < max_levels:
current_level = current_level + 1
print(f"Advancing to level {current_level}")
start_level() # Start the new level
else:
print("You won the entire game!")
game_complete()
def start_level():
print(f"Starting level {current_level}")
print(f"This level will have {2 + current_level} items to remember")
def game_complete():
print("Congratulations! You've mastered the memory sequence!")
Your Task: Complete the Game Logic
Add these final functions to complete your memory game:
Required Functions:
- Success Handling:
def level_completed():
global current_level
# Show success message
status.clear()
status.color("green")
level_text = "Level " + str(current_level) + " Complete!"
status.write(level_text, align="center", font=("Arial", 16, "bold"))
# Advance to next level
current_level = current_level + 1
if current_level > max_levels:
device_unlocked() # Game completed!
else:
wn.ontimer(start_next_level, 2000) # Next level after 2 seconds
Failure Handling:
def sequence_failed():
global game_state
game_state = "waiting"
# Show failure message
status.clear()
status.color("red")
status.write("Wrong sequence! Try again...",
align="center", font=("Arial", 14, "normal"))
# Flash all buttons red to show failure
for button in button_turtles:
button.color("red")
wn.ontimer(reset_after_failure, 1000)
def reset_after_failure():
reset_all_buttons()
wn.ontimer(restart_level, 1000)
def restart_level():
# Restart the current level
status.clear()
status.color("cyan")
level_text = "Level " + str(current_level) + " - Get ready!"
status.write(level_text, align="center", font=("Arial", 12, "normal"))
wn.ontimer(show_sequence, 1500)
- Game Completion:
def device_unlocked():
global game_state
game_state = "complete"
# Clear old messages
status.clear()
instructions.clear()
# Show victory message
title.clear()
title.color("gold")
title.write("DEVICE UNLOCKED!", align="center", font=("Arial", 24, "bold"))
title.goto(0, 120)
title.write("Access Granted to Secure System", align="center", font=("Arial", 14, "normal"))
# Light up all buttons in victory colors
for i in range(4):
button_turtles[i].color(bright_colors[i])
Game Initialization:
def start_game():
global current_level, game_state
current_level = 1
game_state = "waiting"
title.clear()
title.write("MEMORY SEQUENCE DEVICE", align="center", font=("Arial", 16, "bold"))
generate_new_sequence()
wn.ontimer(show_sequence, 1000)
def start_next_level():
status.clear()
status.color("cyan")
level_text = "Level " + str(current_level) + " - Get ready!"
status.write(level_text, align="center", font=("Arial", 12, "normal"))
generate_new_sequence()
wn.ontimer(show_sequence, 1500)
# Add space bar to start game
wn.onkey(start_game, "space")
Final Assembly and Testing
Your Complete Game Structure
By now, you should have all these components:
- Visual Interface: 4 colored buttons and text displays
- Data Management: Lists to store sequences and track progress
- Animation System: Functions to light up buttons and show sequences
- Input System: Keyboard controls and input validation
- Game Logic: Level progression, win/lose conditions
Initial Display Setup
Add this at the end of your code (before wn.mainloop()):
# Set up initial display
title.write("SECURITY PROTOCOL ACTIVE", align="center", font=("Arial", 18, "bold"))
title.goto(0, 120)
title.write("Memory Sequence Required for Access", align="center", font=("Arial", 12, "normal"))
instructions.write("Press SPACE to start | Use keys 1,2,3,4 for buttons",
align="center", font=("Arial", 10, "normal"))
status.write("Security Protocol Ready", align="center", font=("Arial", 12, "normal"))
Testing Your Game
- Run your code – you should see the interface
- Press SPACE – the game should start and show a sequence
- Watch the sequence – buttons should light up one by one
- Press 1,2,3,4 to repeat the sequence
- Complete levels – the game should get progressively harder
- Test failure – deliberately press wrong buttons to test error handling
Troubleshooting Tips
If buttons don’t light up:
- Check that your
button_turtleslist contains all 4 button objects - Verify your
bright_colorslist has 4 colors - Make sure
light_up_button()uses the correct index
If sequences don’t generate:
- Test your
generate_new_sequence()function with print statements - Check that you’re using
global sequencein the function
If keyboard input doesn’t work:
- Ensure you have
wn.listen()before setting up key bindings - Check that your button press functions call
player_press_button()with correct numbers (0-3)
If timing feels wrong:
- Adjust the numbers in
wn.ontimer()calls (values are in milliseconds) - 1000 = 1 second, 500 = 0.5 seconds