Making a Hangman Game
Tutorial: Creating a simple hangman game.
Let's start by importing our required modules.
import turtle
from turtle import done
import random
We will be using turtle to draw our hangman, and programming a game logic will interact with our turtle.
Defining our Variables
"The computer will randomly pick a word from a list" Heh, remember that? Told you the steps will come in handy!
word_list = ["ENTER", "SHOUT", "LOCOMOTIVE", "TECHNOLOGY", "TURTLE", "PROGRAMMING", "SECURITY", "DESIGN",
"ANIMATION", "HACKING", "ROCKET", "ENGINEER", "SCIENCE", "POKEMON", "FORTNITE", "BRAINROT", "SKIBIDI", "TOILET"]
secret_answer = random.choice(word_list)
wrong_tries = 0
max_tries = 6
The code above defines a list of words that could possibly be chosen by the program to be the "secret answer". We use python's built in random module to allow the program to choose a random word from the list above.
wrong_tries and max_tries will help us in game logic later on.
Lists start at 0. This will be important later!
guessed_input = ["_"] * len(secret_answer)
This piece of code will tell the program to print a number of "_" blank spaces to match the number of letters in the chosen "secret answer".
Setting up the "screen" and "pens"
The turtle needs a "canvas" to draw on. I'm going to use white ink on black background because I think its easier on the eyes. You can choose whatever color you like! Go wild!
screen = turtle.Screen()
screen.title("Eric's Hangman")
screen.setup(width=1920, height=1080)
screen.bgcolor("Black")
# Settings for the "pen"
pen = turtle.Turtle()
pen.pensize(5)
pen.color("White")
pen.speed(0) # 0 is instant
Now our turtle is armed with a pen and a canvas. Time to draw!
Drawing our gallow
The gallow will be a fixed part of our program, and will not be changed by other parts of our program.
Let's start by defining our function:
def draw_gallows():
pen.penup()
pen.goto(0, 300)
pen.pendown()
pen.left(90)
pen.forward(200)
pen.left(90)
pen.forward(400)
pen.left(90)
pen.forward(900)
pen.left(90)
pen.forward(800)
draw_gallows()
We can try removing pen.penup() or pen.pendown() to see how the turtle draws strange lines between parts.
It's a great de-bugging introduction.
Drawing our unfortunate victim of capital punishment.
"A wrong guess makes the turtle draw a part of a stick figure."
The above commandment gives us a clue. Again, let's start by defining our function:
def draw_hangman(wrong_tries):
if wrong_tries == 1:
# draw head
elif wrong_tries == 2:
# draw body
...
This code tells our turtle to draw a part of a body everytime the player gets a guess wrong.
if player guess is wrong, then draw a body part. We don't want turtle to draw the same body part over and over
again as that would make a rather uninteresting game of hangm-, hang..thing?
elif is used to tell the program to draw different parts of the body based on the number of wrong tries the player
has guessed.
Here is what the code should look like when completed.
def draw_hangman(wrong_tries):
if wrong_tries == 1: # drawing head
pen.penup()
pen.goto(0, 200)
pen.pendown()
pen.circle(50) # radius
elif wrong_tries == 2: # body
pen.penup()
pen.goto(0, 200)
pen.pendown()
pen.right(90)
pen.forward(300)
elif wrong_tries == 3: # Left hand
pen.penup()
pen.goto(0, 150)
pen.pendown()
pen.right(45)
pen.forward(150)
elif wrong_tries == 4: # Right Hand
pen.penup()
pen.goto(0, 150)
pen.pendown()
pen.left(90)
pen.forward(150)
elif wrong_tries == 5: # Left Leg
pen.penup()
pen.goto(0, -100)
pen.pendown()
pen.right(90)
pen.forward(150)
elif wrong_tries == 6: # Right Leg
pen.penup()
pen.goto(0, -100)
pen.pendown()
pen.left(90)
pen.forward(150)
Making a lose/win screen
How does a player know that they've won, and saved our hero. Or, they lost, and our hero became another victim of ancient and barbaric practices.
Just get the program to tell them duh!
def win_screen():
pen.hideturtle()
pen.color("Green")
pen.penup()
pen.goto(0, 0)
pen.write(f"YOU WIN, YOUR WORD WAS: {secret_answer}",
align="center",
font=("Courier", 30, "bold")
)
def lose_screen():
pen.hideturtle()
pen.color("Red")
pen.penup()
pen.goto(0, 0)
pen.write(f"YOU LOSE, YOUR WORD WAS: {secret_answer}",
align="center",
font=("Courier", 30, "bold")
)
Game logic
Let's take a moment and refresh ourselves with what we want the program to do in terms of our games "logic":
"A player will try to guess the secret word one letter at a time."
guess = screen.textinput("Type a Letter: ", "").upper()
A small pop-up box appears asking the player to type a letter. The .upper part turns lowercase letters to
upper case letters. So "a" and "A" are treated the same.
We also want an "error message" to show when a player enters an invalid character, such as a number. This is called input validation.
while wrong_tries < max_tries: # While the player is still in game
# makes a window for text input
guess = screen.textinput("Type a Letter: ", "").upper()
# INPUT VALIDATION!! always check for empty input before string methods i
if not guess or not guess.isalpha() or len(guess) != 1:
print("Please enter a single alphabet")
continue
The above code means that if the guessed input is not an alphabet using the .isalpha method, or if
the input is longer than one character (you'd be cheating!) using the len method, the command line will print
"Please enter a single alphabet".
"A wrong guess makes the turtle draw a part of a stick figure"
This can also mean:
"A correct guess will NOT make the turtle draw a part of a stick figure"
And that's exactly where we will start with our game logic. In words:
I want my program to check if the guessed letter is in the secret word.
- If it is, I'd like to replace a printed "_" with the correct alphabet, and correct position.
- If it is NOT, I'd like the turtle to draw a part of the hangman.
In code:
guessed_letters = [] #Stores the guessed_letters in a list, that is updated later on.
guessed_pen = turtle.Turtle()
word_pen = turtle.Turtle()
...
...
# Adds the guessed letters to the list "guessed_letters"
guessed_letters.append(guess)
# it is important to index (i). if say secret_answer was "hello", list(enumerate(secret_answer)) --> (0, H), (1, E), (2, L) etc etc
if guess in secret_answer: # If the letter is found in secret_answer
# this means go through every character in secret_answer, starting from i (0, ie the first letter), and return the letter and the position.
for i, letter in enumerate(secret_answer):
if letter == guess: # checks if the guessed letter is in every single position of the secret word
# changes guessed_input to the letter at the correct i position
guessed_input[i] = guess
print(f"Nice one! ", (guessed_input))
word_pen.clear()
word_pen.color("White")
word_pen.penup()
word_pen.goto(0, -600)
word_pen.write(f"{guessed_input}",
align="Center", font=("Courier", 25, "bold"))
else:
wrong_tries += 1 # adds 1 to wrong_tries
draw_hangman(wrong_tries) # starts from step 1
guessed_pen.penup()
guessed_pen.color("White")
guessed_pen.goto(0, -500)
guessed_pen.clear()
guessed_pen.write(
f"Guessed: {guessed_letters}", align="center", font=("Courier", 18, "bold"))
print("Wrong! Try again")
I also want the program to print out a list of alphabets that I've already guessed but was incorrect.
That's what the variables guessed_pen and `word_pen' do.
- Can you identify the
loopin the above code, and explain what it does? - Can you explain what
guessed_letters = []means and why it is important? - BONUS CREDIT: There is a reason why
word_penandguessed_penhad to be defined to be different than the regular pen. Do you know what it is?
Ending the game
"Too many wrong guesses, the turtle finishes the drawing and you lose." "Guess the word before that happens, you win."
In other words, if our number of attempts is equal to our maximum attempt we've set for ourselves, tell the player they lost.
How do we know if the player won? If all the "_" are filled out with correct alphabets! Makes sense?
if wrong_tries == max_tries:
lose_screen()
break
if "_" not in guessed_input: # When all "_" are filled out ie u won
win_screen()
break # what happens if i leave this out?
There you have it! Hangman deconstructed into its bits and pieces and put together in one fun project. Run the program using `python3 run turtle_hangman.py'.
Clone the repo: https://github.com/erictey/turtle_hangman.git