Robert Johns | 15 Mar, 2024
Fact checked by Jim Markus

How To Create A Python Hangman Game With GUI for Beginners

Want to know how to build a Python Hangman Game? In this tutorial, I’ll walk you through this fun and practical Python project step-by-step.

Whether you’re just starting your Python development journey or are keen to learn Python, a Python Hangman Game is a fun project for beginners to learn real-world Python skills.

In this Python Hangman tutorial, you'll:

  • Create an engaging UI for a Python Hangman Game using Tkinter.
  • Utilise OOP to create a scalable and manageable Python app.
  • Implement core functionalities in Python, such as processing user guesses, managing game states, and dynamically updating the display with each guess.
  • Dynamically update the game interface based on user interactions, ensuring a seamless and responsive gaming experience.
  • Apply styling touches and refinements to boost the game's UX.

Through this tutorial, you'll not only develop a fully functional Python Hangman Game but also gain valuable insights into Tkinter for UI design, OOP, and the application of design principles to create engaging and practical Python apps.

To make the most of this tutorial, it helps to have basic Python skills, including familiarity with basic programming and OOP concepts.

Some previous experience with Tkinter, such as working with widgets to build user interfaces, can also be beneficial. However, you don't need to be a Python expert or have prior experience with Python Hangman Games or OOP to follow along.

I’ve also provided the full source code for this Python project so you can follow along, experiment, and even build upon it for your own projects. 

Let’s dive in and start building!

How To Create A Python Hangman Game With GUI

Are you ready to dive into the world of Python development with a hands-on Python project

If you're nodding yes, then you're in the right place because today, we're going to develop a Hangman Game using Python and its Tkinter library for the graphical user interface (GUI). 

This project is a brilliant opportunity for newcomers to Python or GUI application development, as it offers a comprehensive example of how Python can be utilized to create interactive applications.

At the heart of our project, we'll leverage Python's simplicity and Tkinter's ease of use to build a game that accepts user input, manages game logic, and updates the GUI accordingly. 

Python, renowned for its straightforward syntax and powerful libraries, is an ideal language for developing this type of application, blending logic, and interactivity to create something fun and engaging.

In this Hangman Game, Python will oversee the backend logic, including tracking guesses, determining game state (win/lose), and updating the displayed hangman drawing. 

But we'll also dive into creating a visually appealing interface using Tkinter, ensuring our Hangman game is not just functional but also enjoyable to play.

Take a look at the image below to get an idea of what you’re going to build!

How to create a Python Hangman Game with a GUI

You might be wondering, "Will this be challenging?" Don’t worry! 

I've designed this Python project to be beginner-friendly, breaking it down into manageable, easy-to-follow steps. 

Whether you're just starting your Python journey or you're familiar with the language but new to GUI programming, this project is an excellent way to bolster your skills.

So, let's gear up, open our IDE, and get ready to create our very own Hangman Game. 

By the end of this tutorial, not only will you have a functional Hangman Game to showcase in your portfolio, but you'll have deepened your understanding of Python's capabilities in creating interactive applications and GUI development with Tkinter.

Let’s get started and build something awesome!

Project Prerequisites

Before we jump into the coding of our Python Hangman game, let's review the skills you'll need to successfully follow this tutorial. 

Don't worry if you're not a Pythonista just yet! But having a few basics under your belt will make this journey smoother and more enjoyable.

Plus, if you feel a need to brush up in any of these areas, you can always check out a Python course

Remember, we're also here to help, so don’t hesitate to search hackr.io for help as you go along.

Basic Python Knowledge

You should be comfortable with basic Python syntax and programming concepts like variables, loops, conditions, functions, and error handling.

Understanding of Tkinter 

Having some familiarity with Tkinter for GUI development can be beneficial. But don’t worry, I’ll cover the essentials as we build our game.

A Curious and Experimental Mind 

I really believe that when it comes to Python and GUI development, the most effective way to learn is through hands-on experience, making errors, and trying again. 

Be prepared to experiment, modify the code, and perhaps even cause a few glitches (which you'll then resolve). 

I think this is the true essence of learning and development!

You could also consider using an AI coding assistant like GitHub Copilot to help out, but I’d recommend waiting until you’re 100% stuck, as this is where you really learn.

Step 1: Setting Up The Project

Alright! Let's begin by setting up our Python Hangman Game project. 

This initial step is crucial as it establishes the groundwork for our entire game, ensuring we have a structured and organized workspace from the start.

i. Install Python

Before diving into coding, ensure that Python is installed on your computer.

If you haven't installed Python yet, visit the official Python website to find a Python version that’s compatible with your system, and follow the installation instructions.

ii. Choose and Set Up Your IDE or Code Editor

Now it's time to choose an Integrated Development Environment (IDE) or a code editor to develop your Python Hangman game. 

If you’ve read my article on the best Python IDEs, you’ll see that I favor Pycharm and VSCode.

For a more Python-specific IDE, PyCharm is a fantastic choice, offering rich features tailored for Python development.

But I’d also encourage you to check out VSCode if you’re already familiar with that coding environment and you’d like to carry on with what you know. 

Simply head to the VSCode extension marketplace and install the Python extension, and you’ll be good to go.

iii. Create a New Python Project

Once your IDE or code editor is set up, it's time to create a new Python project:

  • Open your IDE or editor and select the option to create a new project.
  • If provided with the option, choose a Python project or just create a general project if your IDE doesn’t specify project types.
  • Name your project something descriptive, like PythonHangmanGame.

iv. Organize Your Project Structure

print("Hello, Python Hangman Game!")

It can be really beneficial to organize your project structure for better management and future scalability. 

Here’s a simple way to structure your Python Hangman game project:

  • src: This directory will contain all your source code files.
  • images: If you plan to use custom images for the the GUI, place them here.
  • sounds: Optional directory for sound effects (e.g., for correct or incorrect guesses).
  • lib: If your project requires external libraries or modules, place them in this directory.

v. Set Up a Version Control System (Optional but Recommended)

Consider initializing a Git repository in your project folder to manage your source code versions. 

Use the command line or your IDE's built-in Git support to create the repository. This step is highly recommended as it helps in tracking changes and collaborating with others.

vi. Verify Project Setup

To ensure everything is set up correctly, try running a simple Python program in your project environment. 

This test will confirm that Python and your IDE or code editor are correctly configured:

vii. Ready Your Development Environment

As we move forward with building the Python Hangman Game, keep your IDE open and familiarize yourself with its layout and features. 

You'll be spending a lot of time here, writing code, debugging, and running your application.

And there you have it! You've successfully set up your Python Hangman Game project. 

With the foundation laid down, we're ready to dive into the exciting parts of building our game. 

Step 2: Designing the Hangman Game Logic

Now, let's delve into designing the Hangman game logic. 

This step is essential as our Hangman game relies on a solid understanding of game mechanics and logic implementation. 

If you’re not totally familiar with the game, in Hangman, players attempt to guess a word by suggesting letters within a certain number of guesses.

Let’s look at this more closely.

i. Understanding Hangman Game Mechanics

The classic game of Hangman involves guessing a word by identifying individual letters. For each game:

  • A secret word is chosen, which the player attempts to guess.
  • The player has a limited number of incorrect guesses before the game is lost (typically, this number is 6, corresponding to the head, body, two arms, and two legs of the hangman).
  • Each correct guess reveals the positions of the letter in the word.
  • Each incorrect guess brings the player one step closer to losing the game as parts of the hangman are drawn.

ii. Implementing the Game Logic

We'll implement the game logic in Python, focusing on managing the secret word, tracking the player's guesses, and determining the game's outcome. 

Here's a high-level overview of the steps involved:

  • Choose a Secret Word: For simplicity, the secret word can be hardcoded or chosen randomly from a list of words.
  • Track Correct and Incorrect Guesses: Maintain two lists to track the letters the player has guessed correctly and incorrectly.
  • Game State Evaluation: After each guess, check if the player has won (guessed all letters of the word) or lost (exceeded the maximum number of incorrect guesses).

iii. Building the Basic Game Logic

Let's sketch out some simple Python code to illustrate these game concepts:

import random

# List of potential secret words
word_list = ["python", "hangman", "programming", "challenge"]
# Randomly select a secret word from the list
secret_word = random.choice(word_list)
# Initialize variables to track guesses and attempts
correct_guesses = set()
incorrect_guesses = set()
attempts_left = 6

# Function to display the current game state
def display_game_state():
  # Display the secret word with guessed letters revealed
  displayed_word = "".join([letter if letter in correct_guesses else "_" for letter in secret_word])
  print(f"Word: {displayed_word}")
  print(f"Incorrect Guesses: {' '.join(incorrect_guesses)}")
  print(f"Attempts Left: {attempts_left}")

# Main game loop
while True:
  display_game_state()
  guess = input("Enter your guess: ").lower()
 
  # Check if the guess is in the secret word
  if guess in secret_word:
      correct_guesses.add(guess)
      # Check for win condition
      if set(secret_word).issubset(correct_guesses):
          print("Congratulations! You've guessed the word!")
          break
  else:
      incorrect_guesses.add(guess)
      attempts_left -= 1
      # Check for lose condition
      if attempts_left == 0:
          print("Game Over! You've run out of attempts.")
          print(f"The secret word was: {secret_word}")
          break

In this basic code, we’ve outlined the core logic for a simple console-based Hangman game. 

As we progress through this tutorial, we'll expand upon this foundation, integrating it with a graphical user interface using Tkinter to enhance the player's experience.

In the next steps, we'll dive into setting up Tkinter and linking our game logic to a GUI, creating an interactive and visually appealing Hangman game.

Let’s get coding!

Step 3: Introduction to Tkinter for GUI Development

Let's roll up our sleeves and dive into creating the graphical user interface (GUI) for our Hangman game using Tkinter, Python's standard GUI library. 

Tkinter is built-in with Python, making it a convenient choice for creating simple and effective GUI applications without the need for additional installations.

Note that we'll adopt an object-oriented approach for this project to enhance the structure and maintainability of our code, making it easier to understand and extend.

This also makes it a great way to learn the basics of OOP.

i. Check if Tkinter is Installed

Before we start coding, let's ensure Tkinter is available in your Python environment. While Tkinter typically comes with Python, it's good practice to verify its presence. 

Open your terminal or command prompt and enter the following:

python -m tkinter

This command should open a simple Tkinter window, indicating that Tkinter is installed and working correctly. 

If it doesn't, you may need to install Tkinter by referring to Python documentation or by heading to PyPi.

ii. Setting Up Your GUI Project File

In your project directory, create a Python file named hangman_game.py

This file will contain both the GUI components and the game logic, integrated within a single class structure for simplicity and efficiency.

iii. Creating the Main Window with Tkinter

Let’s start by defining a class for our Hangman Game, encapsulating both the game logic and the GUI components. 

Start by setting up the main window in this class:

import tkinter as tk

class HangmanGame:
  def __init__(self, master):
      self.master = master
      self.master.title("Hangman Game")
      self.master.geometry("900x600")
      # Further GUI setup and game logic will be added here

def main():
  root = tk.Tk()
  game = HangmanGame(root)
  root.mainloop()

if __name__ == "__main__":
  main()

In this code, we've:

  • Imported the Tkinter module to utilize its GUI functionalities.
  • Created a HangmanGame class, introducing an OOP approach to structure our game. This class will contain methods for setting up the GUI and handling the game logic.
  • Initialized the main application window (master) within the class, setting its title to "Hangman Game" and specifying its size to 900x600 pixels.
  • Defined a main function to create the Tkinter root window, instantiate our HangmanGame class with this window, and start the Tkinter event loop.

Running this script will open a window demonstrating the basics of Tkinter in action.

iv. Adding Widgets

Tkinter supports various widgets that can be added to the GUI, such as labels, buttons, and canvases. 

These will be crucial for displaying the hangman drawing, the word to guess, letters already guessed, and accepting user input.

In the subsequent steps, we'll dive deeper into how to use these widgets to build the functional parts of our Hangman game interface.

This step sets the stage for developing a full-fledged GUI for our Hangman game. 

In the next steps, we'll expand on this, incorporating the game logic and enhancing the interface to create an engaging and interactive game experience.

Step 4: Building the Game Interface with Tkinter

Now that we've introduced Tkinter and set up a basic window within an object-oriented framework, let’s set to work on further developing our Hangman game's GUI. 

We'll focus on designing the layout, adding interactive widgets, and preparing the game board to display essential game elements using our HangmanGame class.

i. Designing the Layout

Within our HangmanGame class, let’s aim to create a cohesive layout that includes:

  • A top section for the hangman drawing as incorrect guesses accumulate.
  • A middle section to reveal the word being guessed, with blanks for letters yet to be guessed.
  • A bottom section containing alphabet buttons for player input.

ii. Implementing the Hangman Drawing Area

Let’s utilize Tkinter's Canvas widget within our class to dynamically display the hangman drawing:

def initialize_gui(self):
  self.hangman_canvas = tk.Canvas(self.master, width=300, height=300, bg="white")
  self.hangman_canvas.pack(pady=20)
  # Additional GUI setup continues here...

In this code, we've:

  • Embedded the Canvas widget creation within the initialize_gui method of our HangmanGame class. This method orchestrates the setup of our game's GUI.
  • Created a Canvas named hangman_canvas as part of our class. This canvas, with a 300x300 pixel size and a white background, is designated for the hangman drawing.
  • Used pack() with vertical padding to place the canvas appropriately within the window.

iii. Displaying the Word to Guess

Let’s now incorporate Label widgets into our class so that we can show the word with blanks or correctly guessed letters:

def initialize_gui(self):
  # Previous GUI setup code...
  self.word_display = tk.Label(self.master, text="_ " * len(self.secret_word), font=("Helvetica", 30))
  self.word_display.pack(pady=(40, 20))

In this code, we've:

  • Created a Label widget within the initialize_gui method to display the word. Initially, it shows an underscore for each word letter in the secret_word.
  • Selected a font size of 30 for clarity and readability, ensuring the underscores and letters are easily distinguishable.
  • Positioned the label with pack(), applying padding to set it apart from other elements.

iii. Adding Alphabet Buttons for Guesses

When it comes to handling player interactions, let’s generate alphabet buttons within our class, linking each to a guess-handling method:

def initialize_gui(self):
  # Previous GUI setup code...
  self.buttons_frame = tk.Frame(self.master)
  self.buttons_frame.pack(pady=20)
  self.setup_alphabet_buttons()

In this code, we've:

  • Defined a setup_alphabet_buttons method within our class to create and configure buttons for each letter in the alphabet.
  • Established a Frame widget to group alphabet buttons, ensuring organized placement within the GUI.
  • For each alphabet letter, created a Button widget. These buttons invoke the guess_letter method with the respective letter as an argument upon being clicked, facilitating player interaction with the game.

Nice work! We’ve now created the foundation for our interactive Hangman game. 

If you’re new to the world of OOP, know that by embedding our GUI setup and interaction logic within the HangmanGame class, we've laid a solid foundation for building a fully interactive Hangman game. 

The idea here is that the OOP approach not only organizes our code effectively, but also sets us up for seamless integration of game logic and GUI updates in the next steps.

Let’s keep this momentum going!

Step 5: Integrating the Game Logic with the GUI

Now that we've laid out our Hangman Game's GUI, it's time to breathe life into it by integrating the game logic. 

This will make our game fully interactive, responding to player inputs and dynamically updating the GUI.

i. Initializing the GUI & Random Word Selections

First things first, let’s initialize our game by calling the initialize_gui method along with a new method that we’ll define to select a random secret word:

import random

class HangmanGame:
  def __init__(self, master):
      self.master = master
      self.master.title("Hangman Game")
      self.master.geometry("900x600")
      self.word_list = ["PYTHON", "JAVASCRIPT", "KOTLIN", "JAVA", "RUBY", "SWIFT"]
      self.secret_word = self.choose_secret_word()
      self.correct_guesses = set()
      self.incorrect_guesses = set()
      self.attempts_left = 7
      self.initialize_gui()

  def choose_secret_word(self):
      return random.choice(self.word_list)

In this code, we've:

  • Imported the random module to help with random word selection.
  • Added a word_list attribute to store potential secret words. This list can be easily extended or modified to include any number of words.
  • Introduced the choose_secret_word method, which randomly selects a word from our wordlist using random.choice(). This method is called when initializing self.secret_word during the creation of a HangmanGame instance.
  • Ensured that the selection of the secret word is integrated into the game initialization process, making the game different each time it's played.

ii. Updating the Hangman Canvas

Let’s now add a method to our HangmanGame class to update the hangman drawing based on incorrect guesses:

def update_hangman_canvas(self):
  self.hangman_canvas.delete("all")  # Clear the canvas for redrawing
  incorrect_guesses_count = len(self.incorrect_guesses)
  if incorrect_guesses_count >= 1:
      self.hangman_canvas.create_line(50, 180, 150, 180)  # Base
  # Additional drawing logic here for each part of the hangman

In this code, we've:

  • Added an update_hangman_canvas method to the HangmanGame class. This method clears the canvas and redraws the hangman figure based on the current number of incorrect guesses.
  • Utilized Tkinter's create_line and create_oval methods within conditional blocks to progressively draw the hangman as incorrect guesses accumulate.

iii. Handling Letter Guesses

Within the class, we define the logic to handle letter guesses for the hidden word, updating the game state and refreshing GUI elements as needed:

def guess_letter(self, letter):
  if letter in self.secret_word and letter not in self.correct_guesses:
      self.correct_guesses.add(letter)
  elif letter not in self.incorrect_guesses:
      self.incorrect_guesses.add(letter)
      self.attempts_left -= 1
      self.update_hangman_canvas()
 
  self.update_word_display()
  self.check_game_over()

def update_word_display(self):
  displayed_word = " ".join([letter if letter in self.correct_guesses else "_" for letter in self.secret_word])
  self.word_display.config(text=displayed_word)

def check_game_over(self):
  if set(self.secret_word).issubset(self.correct_guesses):
      self.display_game_over_message("Congratulations, you've won!")
  elif self.attempts_left == 0:
      self.display_game_over_message(f"Game over! The word was: {self.secret_word}")

In this code, we've:

  • Implemented a guess_letter method to update the sets of correct and incorrect guesses, decrease attempts_left for incorrect guesses, and invoke methods to update the canvas and word display.
  • Used update_word_display to refresh the displayed word on the GUI, revealing any correctly guessed letters.
  • Created check_game_over to evaluate if the game has been won or lost, displaying an appropriate message through display_game_over_message.

iv. Connecting Buttons to the Guess Function

To ensure alphabet buttons are correctly linked to the guess_letter function, we adjust the button setup in the setup_alphabet_buttons method, utilizing the class's methods for game interaction:

def setup_alphabet_buttons(self):
  alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  upper_row = alphabet[:13]  # First half of the alphabet
  lower_row = alphabet[13:]  # Second half of the alphabet
 
  upper_frame = tk.Frame(self.buttons_frame)
  upper_frame.pack()
  lower_frame = tk.Frame(self.buttons_frame)
  lower_frame.pack()

  for letter in upper_row:
      button = tk.Button(upper_frame, text=letter, command=lambda l=letter: self.guess_letter(l), width=4, height=2)
      button.pack(side="left", padx=2, pady=2)

  for letter in lower_row:
      button = tk.Button(lower_frame, text=letter, command=lambda l=letter: self.guess_letter(l), width=4, height=2)
      button.pack(side="left", padx=2, pady=2)

In this code, we've:

  • Defined the setup_alphabet_buttons method within the HangmanGame class to create interactive buttons for each letter in the English alphabet.
  • Initialized a string alphabet containing all uppercase letters, A-Z, to iterate over and create a button for each letter.
  • Split the alphabet into two halves: upper_row and lower_row.
  • Created two frames within self.buttons_frame: one for each row of letters. This ensures that the alphabet is neatly divided into two rows, making all letters accessible without overcrowding the screen.
  • Associated each button with the guess_letter method using a lambda function, enabling the game to react to player guesses by checking the chosen letter against the secret word, updating the game state, and refreshing the GUI accordingly.
  • Utilized pack() for button placement, arranging them side by side with consistent padding to ensure the interface is visually appealing and user-friendly.

v. Adding Game Over Messages

To round things off, let’s define a display_game_over_message method that show the user the result of the game when reaches its conclusion:

def display_game_over_message(self, message):
  # Hide the alphabet buttons by hiding the entire buttons_frame
  self.buttons_frame.pack_forget()

  # Display the game over message in the now-empty area
  self.game_over_label = tk.Label(self.master, text=message, font=("Helvetica", 18), fg="red")
  self.game_over_label.pack(pady=(10, 20))

In this code, we've:

  • Utilized pack_forget() on self.buttons_frame to hide the alphabet buttons from view. This effectively removes the button area from the game interface, preventing further guesses.
  • Created a Label widget, self.game_over_label, to display the game over message in the area previously occupied by the alphabet buttons. 

Great work! Our Hangman Game is really taking shape now! Let’s keep this effort up and move on to the next stage, where we'll add graphics for the Hangman.

Step 6: Adding Graphics for Hangman

Now it’s time to enhance our Hangman Game with graphics that not only make it visually appealing but also enrich the player's experience.

Let's now focus on refining the hangman drawing method with more detailed graphics.

i. Refining the Hangman Canvas Drawing

We previously introduced a method to update the hangman drawing based on incorrect guesses. 

Now, we'll enhance this drawing to include more detailed graphical elements, potentially making each stage of the hangman's appearance more visually distinct and engaging.

def update_hangman_canvas(self):
  self.hangman_canvas.delete("all")  # Clear the canvas before redrawing
  stages = [self.draw_head, self.draw_body, self.draw_left_arm, self.draw_right_arm, self.draw_left_leg, self.draw_right_leg, self.draw_face]
  for i in range(len(self.incorrect_guesses)):
      if i < len(stages):
          stages[i]()  # Call the drawing method for each incorrect guess

In this enhanced code, we use a list of methods (stages) that each draw a part of the hangman. 

As the number of incorrect guesses increases, we sequentially invoke these methods to progressively draw the hangman.

ii. Drawing Detailed Hangman Parts

Let's now implement methods for each part of the hangman's body, aiming for a bit more detail than simple lines:

def draw_head(self):
      self.hangman_canvas.create_oval(125, 50, 185, 110, outline="black")

def draw_body(self):
  self.hangman_canvas.create_line(155, 110, 155, 170, fill="black")

def draw_left_arm(self):
  self.hangman_canvas.create_line(155, 130, 125, 150, fill="black")

def draw_right_arm(self):
  self.hangman_canvas.create_line(155, 130, 185, 150, fill="black")

def draw_left_leg(self):
  self.hangman_canvas.create_line(155, 170, 125, 200, fill="black")

def draw_right_leg(self):
  self.hangman_canvas.create_line(155, 170, 185, 200, fill="black")

def draw_face(self):
  self.hangman_canvas.create_line(140, 70, 150, 80, fill="black") # Left eye
  self.hangman_canvas.create_line(160, 70, 170, 80, fill="black") # Right eye
  # Draw a sad mouth
  self.hangman_canvas.create_arc(140, 85, 170, 105, start=0, extent=-180, fill="black")

In this code, we've:

  • Implemented separate methods for drawing each part of the hangman, such as draw_head, draw_body, etc. within the HangmanGame class. These methods use Tkinter's create_oval and create_line functions to add shapes to the canvas, creating a more detailed hangman figure.
  • Introduced a draw_face method as the final stage, adding a simple face to the hangman to indicate the game's conclusion. This method uses create_line for the eyes and create_arc for the mouth, providing a simple yet expressive face.

Nice work! By adding detailed graphics for the hangman, you’ve really elevated the gameplay while also leveling up the overall aesthetics of the game.

Step 7: Adding Game Reset Functionality

Let’s wrap things up by adding game reset functionality. This is will allow our users to start a new game easily without needing to restart the application. 

To do this, we’ll create a method to reset the game and add a button that players can click to trigger the reset.

i. Implementing the Reset Game Method

Let’s start with the reset_game method, which will include selecting a new secret word, clearing guesses, resetting attempts, and updating the GUI to its initial state.

def reset_game(self):
  self.secret_word = self.choose_secret_word()
  self.correct_guesses = set()
  self.incorrect_guesses = set()
  self.attempts_left = 7

  self.hangman_canvas.delete("all")
  self.update_word_display()
 
  for frame in self.buttons_frame.winfo_children():
      for button in frame.winfo_children():
          button.configure(state=tk.NORMAL)
 
  if hasattr(self, 'game_over_label'):
      self.game_over_label.destroy()

In this code, we’ve:

  • Reset the game's state by selecting a new secret word, clearing the sets of correct and incorrect guesses, and restoring the initial number of attempts.
  • Cleared the drawing canvas to remove any hangman images from previous games, preparing for a fresh start.
  • Updated the word display to reflect the new secret word's placeholders.
  • Re-enabled all alphabet buttons, making them clickable again for the new game.
  • Conditionally removed the game over message, if it was displayed, to reset the game interface to its initial state.

ii. Adding the Reset Button to the GUI

Now, let’s add a button to the GUI that allows the player to reset the game. This button will call the reset_game method when clicked.

def initialize_gui(self):
  # Existing GUI setup code...
  # Add reset game button
  self.reset_button = tk.Button(self.master, text="Reset Game", command=self.reset_game)
  self.reset_button.pack(pady=(10, 0))

In this code, we’ve:

  • Continued the GUI setup by adding the alphabet buttons to the interface.
  • Introduced a "Reset Game" button into the GUI. This button will call the reset_game method when clicked, allowing players to easily restart the game at any point.
  • Placed the reset button below the other game elements, adding appropriate vertical padding for clear separation and visual appeal.

Note that with our new Reset button, we’ll need a slightly larger overall window to accommodate it, so let’s also adjust our main window size:

def __init__(self, master):
      self.master = master
      self.master.title("Hangman Game")
      self.master.geometry("900x650")
      # Rest of code… 

iii. Adding Game Restart Functionality

Now that we have a reset method, why don’t we make further use of this by adding a game restart button?

This will only appear after the game is over and will give a clear signal that the user can start over.

We’ll start by modifying the display_game_over_message method to show a "Restart" button alongside the game over message. 

This button will leverage the existing reset_game method but will only be displayed when the game concludes, offering a clear call to action for the player.

Note that we’ll also hide the reset button when this happens so the UX is nice and clear for our players.

def display_game_over_message(self, message):
  # Hide the reset button
  self.reset_button.pack_forget()
  # Hide the alphabet buttons and display the game over message
  self.buttons_frame.pack_forget()
  self.game_over_label = tk.Label(self.master, text=message, font=("Helvetica", 18), fg="red")
  self.game_over_label.pack(pady=(10, 20))

  # Display the Restart button
  self.restart_button = tk.Button(self.master, text="Restart Game", command=self.reset_game, width=20, height=2)
  self.restart_button.pack(pady=(10, 20))

In this code, we’ve:

  • Hidden the reset_button to indicate that the game is now over.
  • Added a "Restart Game" button below the game over message. This button, when clicked, triggers the game's reset functionality, offering a straightforward way for players to start a new game after the current one concludes.

Now, since the "Restart" button becomes part of the game-over sequence, the reset_game method also needs some slight adjustments to ensure it properly resets the game state and also manages the visibility of the "Restart" button correctly.

def reset_game(self):
  # Re-show the reset button
  self.reset_button.pack(pady=(10, 0))

  # Reset game state and GUI elements as previously outlined
  # Hide the game over label and the Restart button when the game is reset
  if hasattr(self, 'game_over_label') and self.game_over_label.winfo_exists():
      self.game_over_label.pack_forget()
  if hasattr(self, 'restart_button') and self.restart_button.winfo_exists():
      self.restart_button.pack_forget()

  # Ensure the alphabet buttons frame and other interactive elements are visible again
  self.buttons_frame.pack()

In this code, we’ve:

  • Used the .pack() method to re-show the reset_button with a fresh game.
  • Added logic to hide the game over message and the "Restart Game" button when the game is reset by checking if these elements exist and currently displayed, then using pack_forget() to remove them from view.
  • Made sure to repack the alphabet buttons frame, ensuring that the interactive part of the game's interface is made visible again for the new game session. 

Nice work! We now have a fully functional Python Hangman Game! Before we to dive into some testing to ensure our game functions the way it should, how about we polish the styling?

Step 8: Enhanced Styling [Optional]

In general, taking the time to improve the visual aesthetics of your Hangman Game can really elevate the overall user experience.

The easiest way to do this is by changing the color scheme and applying stylish fonts. 

So, let’s adjust the main window's background color, customize the button appearance for a more modern look, and select a stylish font for the text elements.

i. Changing the Main Window's Background Color

To set the main window's background to something like light blue, you can modify the __init__ method in the HangmanGame class to include a configuration for the master's background color:

def __init__(self, master):
  self.master = master
  self.master.title("Hangman Game")
  self.master.geometry("900x650")
  self.master.configure(bg='light blue')  # Set the background color
  # Remaining initialization code...

In this code, we’ve simply added a background color parameter of light blue to the main window.

To ensure the design is coherent, this can also be added to both the labels for the game over message and word guesses:

def initialize_gui(self):
  # Existing code...
  self.word_display = tk.Label(self.master, text="_ " * len(self.secret_word), font=("Helvetica", 30), bg='light blue')
  self.word_display.pack(pady=(40, 20))

   

def display_game_over_message(self, message):
  # Existing code...
  self.game_over_label = tk.Label(self.master, text=message, font=stylish_font, fg="red", bg='light blue')
  self.game_over_label.pack(pady=(10, 20))

ii. Customizing Button Appearance

Now, we can also change the background color and font properties of our buttons to elevate the overall aesthetic.

Let’s start with the alphabet buttons:

def setup_alphabet_buttons(self):
  # Custom button appearance
  button_bg = "#4a7a8c"  # Example: a nice shade of blue
  button_fg = "white"  # Text color
  button_font = ("Helvetica", 12, "bold")  # Example: bold Helvetica font

  # Setup code for upper and lower rows...
  for letter in upper_row:
      button = tk.Button(upper_frame, text=letter, command=lambda l=letter: self.guess_letter(l),
                          width=4, height=2, bg=button_bg, fg=button_fg, font=button_font)
      button.pack(side="left", padx=2, pady=2)

  # Repeat for lower_row buttons...

In this code, we’ve used a new background color, text color, and font for our buttons.

We can also apply this same styling to our Reset and Restart Game buttons:

def initialize_gui(self):
  # Existing code...
  button_bg = "#4a7a8c"
  button_fg = "white"
  button_font = ("Helvetica", 12, "bold")
  self.reset_button = tk.Button(self.master, text="Reset Game", command=self.reset_game, width=20, height=2, bg=button_bg, fg=button_fg, font=button_font)
  self.reset_button.pack(pady=(10, 0))
 
def display_game_over_message(self, message):
  # Existing code...
  button_bg = "#4a7a8c"
  button_fg = "white"
  button_font = ("Helvetica", 12, "bold")

  if not hasattr(self, 'restart_button'):
      self.restart_button = tk.Button(self.master, text="Restart Game", command=self.reset_game, width=20, height=2, bg=button_bg, fg=button_fg, font=button_font)
  self.restart_button.pack(pady=(10, 20))

iii. Using Stylish Fonts for Text Elements

Now, let’s select a modern and stylish font for the game's text elements, such as the guessed letter display, and the game over message. 

Of course, feel free to experiment and choose your favorite typeface:

def display_game_over_message(self, message):
  # Existing code...
  stylish_font = ("Arial", 18, "italic")
 
  self.game_over_label = tk.Label(self.master, text=message, font=stylish_font, fg="red", bg='light blue')
  self.game_over_label.pack(pady=(10, 20))

By adding these styling enhancements, we’ve not only made the game more enjoyable to interact with, but this is also a great way to learn how to make simple adjustments that significantly improve the UX of your app.

Great job! We’re now ready to dive into our testing phase for this Hangman Game.

Step 9: Testing the Game

Fantastic work on developing your Python Hangman Game! 

Now, it's time to apply the finishing touches and rigorously test the application to ensure its functionality is flawless and the user experience is intuitive and engaging. 

For our Hangman Game, testing could involve several key areas: functionality, usability, and interface design. 

Let’s take a look at how you could approach each of these:

i. Functionality Testing

  • Game Logic: Verify that the game correctly identifies correct and incorrect guesses, updates the display accordingly, and tracks the number of attempts left accurately.
  • Winning and Losing Conditions: Ensure the game accurately concludes when a player wins (guesses the word correctly) or loses (runs out of attempts), displaying the appropriate game-over message.
  • Reset and Restart: Test the reset and restart functionalities to confirm they correctly reset the game state and GUI, allowing for a new game to start seamlessly.
  • Word Selection: Confirm the secret word selection works as intended, providing a variety of words across different game sessions.

ii. Usability Testing

  • User Interface and Experience: Gather feedback on the game's interface and controls. Are the rules clear? Is the game easy to play and understand? Is the restart/reset process intuitive?
  • Performance: Evaluate the game's responsiveness. Are there any noticeable delays or lag when interacting with the GUI, especially when guessing letters or resetting the game?
  • Accessibility: Assess the game's accessibility features, such as readability of text, color contrast, and potential support for keyboard-only navigation.

iii. Interface Design Testing

  • Consistency and Responsiveness: Check the game's appearance across different screen sizes and resolutions (if applicable) to ensure consistent styling and layout.
  • Aesthetic Appeal: Evaluate the visual design of your game, including the choice of colors, fonts, and overall layout. Does the game visually appeal to your target audience?

When it comes to conducting these tests, much of the functionality and usability testing will be manual due to the interactive nature of this Hangman Game.

I’d also highly encourage you to get a small group of real users to use the application and provide feedback on usability and any bugs they encounter.

And remember that testing should be an iterative process. After fixing issues, retest to ensure no new problems have been introduced and that the original issue has been resolved.

Now that you’ve reached this stage, other steps I’d encourage you to consider include:

Documentation and Sharing:

  • Consider drafting a README file if you plan to showcase your project on platforms like GitHub, detailing the project setup and any noteworthy features.
  • Share your project within developer communities or on social media to engage with a broader audience and gather additional feedback.

Reflect and Plan Next Steps:

  • Reflect on the knowledge gained through this project and contemplate how these learnings can be applied to future endeavors.
  • Consider expanding your Hangman Game with more complex features, like sound effects, difficulty levels, animations, and a dictionary API for more words to guess from.

Great job on building and refining your Python Hangman Game! Take a moment to appreciate your hard work!

Whether you're building this for fun, as a learning experience, or as a portfolio piece, you've developed valuable skills in programming, problem-solving, and user interface design.

Be proud of your work, share it with others, and consider what project you'll take on next!

Step 10: Final Touches and Packaging

After thorough testing and refinements, it's time to apply the final touches to your Python Hangman Game and prepare it for distribution. 

This step is all about ensuring your application is polished, user-friendly, and ready for others to use.

i. Final Review and Refinement

  • Code Cleanup: Review your code to remove or refactor any redundant or unused parts. Ensure that your code is well-commented and follows best practices for naming conventions and structure, making it readable and maintainable.
  • UI Consistency Check: Make sure all elements of your GUI are consistent with the game's theme and design. Test the game on different window sizes (if resizable) to ensure the layout adjusts well and remains user-friendly across various conditions.
  • Optimization: Assess the game's performance, focusing on quick responsiveness to user inputs and efficient handling of game logic and GUI updates. Optimize any parts of the code that cause delays or use resources inefficiently.
  • Security Review: While a Hangman Game may not deal with sensitive data, ensuring your code is secure against common vulnerabilities is good practice, especially if expanding the game or integrating it with web services in the future.

ii. Documentation

  • User Guide: Create a simple user guide that provides instructions on how to start the game, the rules of Hangman, and how to use any specific features you've implemented (like resetting the game or changing difficulty levels, if applicable).
  • Developer Documentation: Comment your code thoroughly to explain the purpose of functions and the logic of more complex sections. This documentation is invaluable for future you or anyone else who may work on or learn from your project.

iii. Packaging and Distribution

  • Packaging the Application: For Python applications, consider creating an executable file for easy distribution. Tools like PyInstaller can package your Python script into standalone executables for Windows, macOS, and Linux.
  • Distribution Platforms: Choose platforms for sharing your game. GitHub is great for open-source projects, offering version control and collaboration features. Other options include personal blogs, websites, or Python-specific repositories like PyPI if you package your game as a library.
  • Considerations for Web Applications: If you decide to make a web version of your Hangman game in the future, frameworks like Flask or Django can help you transition the game into a web application. Note that this involves additional considerations like handling client-server interactions and ensuring web security practices.

Next Steps & Further Learning

Congratulations on successfully building your own Python Hangman Game!

This is a significant achievement, but your learning journey doesn't stop here. There are many ways to further your skills in Python development. Let's explore some ideas:

Learn More About Python

  • Python Enhancements: Explore more advanced Python concepts and apply them to your game. This could be score tracking, difficulty levels, multiplayer support, adding sound effects or animations, letting users customize the UI, or adding integration with a dictionary API for more words to guess.
  • Explore Libraries: Experiment with Python libraries to see how they can be used to build more dynamic and complex Python applications.

Join Online Communities and Collaborate

  • Engage in Forums: Participate in Python development forums and communities. Share your email client, get feedback, and learn from others.
  • Contribute to Open Source: Consider making your email client open-source and collaborate with others to improve it.

Keep Up with Trends and Best Practices

Stay updated with the latest trends in Python development. Subscribe to blogs like hackr.io, watch webinars, and join online courses.

Document and Share Your Learning Journey

  • Blog About Your Project: Write about your development process, challenges you faced, and how you overcame them. Share your blog with the developer community.
  • Share Your Code: Publish your code on platforms like GitHub. This not only showcases your work but also allows others to learn from your project.

Challenge Yourself Regularly

Take part in coding challenges or hackathons to sharpen your skills and learn new techniques.

And if you're hungry for more Python projects, check back regularly as we’re constantly adding new step-by-step tutorials.

Python Hangman Game Full Source Code

import tkinter as tk
import random

class HangmanGame:
  def __init__(self, master):
      self.master = master
      self.master.title("Hangman Game")
      self.master.geometry("900x650")
      self.master.configure(bg='light blue')
      self.word_list = ["PYTHON", "JAVASCRIPT", "KOTLIN", "JAVA", "RUBY", "SWIFT"]
      self.secret_word = self.choose_secret_word()
      self.correct_guesses = set()
      self.incorrect_guesses = set()
      self.attempts_left = 7
      self.initialize_gui()

  def initialize_gui(self):
      button_bg = "#4a7a8c"
      button_fg = "white"
      button_font = ("Helvetica", 12, "bold")
      self.hangman_canvas = tk.Canvas(self.master, width=300, height=300, bg="white")
      self.hangman_canvas.pack(pady=20)
      self.word_display = tk.Label(self.master, text="_ " * len(self.secret_word), font=("Helvetica", 30), bg='light blue')
      self.word_display.pack(pady=(40, 20))
      self.reset_button = tk.Button(self.master, text="Reset Game", command=self.reset_game, width=20, height=2, bg=button_bg, fg=button_fg, font=button_font)
      self.reset_button.pack(pady=(10, 0))
      self.buttons_frame = tk.Frame(self.master)
      self.buttons_frame.pack(pady=20)
      self.setup_alphabet_buttons()
 
  def setup_alphabet_buttons(self):
      button_bg = "#4a7a8c"
      button_fg = "white"
      button_font = ("Helvetica", 12, "bold")

      alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      upper_row = alphabet[:13]
      lower_row = alphabet[13:]
     
      upper_frame = tk.Frame(self.buttons_frame)
      upper_frame.pack()
      lower_frame = tk.Frame(self.buttons_frame)
      lower_frame.pack()

      for letter in upper_row:
          button = tk.Button(upper_frame, text=letter, command=lambda l=letter: self.guess_letter(l), width=4, height=2, bg=button_bg, fg=button_fg, font=button_font)
          button.pack(side="left", padx=2, pady=2)

      for letter in lower_row:
          button = tk.Button(lower_frame, text=letter, command=lambda l=letter: self.guess_letter(l), width=4, height=2, bg=button_bg, fg=button_fg, font=button_font)
          button.pack(side="left", padx=2, pady=2)
     
  def choose_secret_word(self):
      return random.choice(self.word_list)

  def update_hangman_canvas(self):
      self.hangman_canvas.delete("all")
      stages = [self.draw_head, self.draw_body, self.draw_left_arm, self.draw_right_arm,
                self.draw_left_leg, self.draw_right_leg, self.draw_face]
      for i in range(len(self.incorrect_guesses)):
          if i < len(stages):
              stages[i]()
 
  def draw_head(self):
      self.hangman_canvas.create_oval(125, 50, 185, 110, outline="black")

  def draw_body(self):
      self.hangman_canvas.create_line(155, 110, 155, 170, fill="black")

  def draw_left_arm(self):
      self.hangman_canvas.create_line(155, 130, 125, 150, fill="black")

  def draw_right_arm(self):
      self.hangman_canvas.create_line(155, 130, 185, 150, fill="black")

  def draw_left_leg(self):
      self.hangman_canvas.create_line(155, 170, 125, 200, fill="black")

  def draw_right_leg(self):
      self.hangman_canvas.create_line(155, 170, 185, 200, fill="black")

  def draw_face(self):
      self.hangman_canvas.create_line(140, 70, 150, 80, fill="black")
      self.hangman_canvas.create_line(160, 70, 170, 80, fill="black")
      self.hangman_canvas.create_arc(140, 85, 170, 105, start=0, extent=-180, fill="black")

  def guess_letter(self, letter):
      if letter in self.secret_word and letter not in self.correct_guesses:
          self.correct_guesses.add(letter)
      elif letter not in self.incorrect_guesses:
          self.incorrect_guesses.add(letter)
          self.attempts_left -= 1
          self.update_hangman_canvas()
     
      self.update_word_display()
      self.check_game_over()

  def update_word_display(self):
      displayed_word = " ".join([letter if letter in self.correct_guesses else "_" for letter in self.secret_word])
      self.word_display.config(text=displayed_word)

  def check_game_over(self):
      if set(self.secret_word).issubset(self.correct_guesses):
          self.display_game_over_message("Congratulations, you've won!")
      elif self.attempts_left == 0:
          self.display_game_over_message(f"Game over! The word was: {self.secret_word}")
 
  def display_game_over_message(self, message):
      stylish_font = ("Arial", 18, "italic")
      button_bg = "#4a7a8c"
      button_fg = "white"
      button_font = ("Helvetica", 12, "bold")

      self.reset_button.pack_forget()
      self.buttons_frame.pack_forget()
     
      self.game_over_label = tk.Label(self.master, text=message, font=stylish_font, fg="red", bg='light blue')
      self.game_over_label.pack(pady=(10, 20))

      if not hasattr(self, 'restart_button'):
          self.restart_button = tk.Button(self.master, text="Restart Game", command=self.reset_game, width=20, height=2, bg=button_bg, fg=button_fg, font=button_font)
      self.restart_button.pack(pady=(10, 20))
 
  def reset_game(self):
      self.secret_word = self.choose_secret_word()
      self.correct_guesses = set()
      self.incorrect_guesses = set()
      self.attempts_left = 7

      self.hangman_canvas.delete("all")
      self.update_word_display()
     
      for frame in self.buttons_frame.winfo_children():
          for button in frame.winfo_children():
              button.configure(state=tk.NORMAL)
     
      self.reset_button.pack(pady=(10, 0))
     
      if hasattr(self, 'game_over_label') and self.game_over_label.winfo_exists():
          self.game_over_label.pack_forget()
      if hasattr(self, 'restart_button') and self.restart_button.winfo_exists():
          self.restart_button.pack_forget()

      self.buttons_frame.pack()

def main():
  root = tk.Tk()
  game = HangmanGame(root)
  root.mainloop()

if __name__ == "__main__":
  main()

Wrapping Up

Building a Python Hangman Game is a great way to enhance your Python development skills and delve into creating interactive Python applications.

By creating this interactive Python Hangman Game, you've navigated through a range of challenges, including devising a user-friendly interface, handling game logic, and dynamically updating the game interface in response to user actions. 

In this tutorial, you’ve learned how to:

  • Use Tkinter to craft a clean and visually appealing GUI for the Hangman game.
  • Write Python code to manage the game's logic, including processing guesses, determining game outcomes, and handling word selection.
  • Implement OOP to effectively manage your codebase and allow future scalability.
  • Dynamically adjust Tkinter components to reflect the game's progress, incorrect guesses, and the reveal of the secret word.
  • Respond to user inputs by incorporating event listeners for letter guessing and providing options to restart or exit the game.

You now possess the essential tools and knowledge needed to further develop and expand this Python Hangman Game. 

Potential enhancements could include integration with dictionary APIs, user authentication to maintain high scores and track progress over time, multiplayer capabilities, or integration into web applications or larger Python projects for a broader reach and engagement.

Your journey into the world of Python doesn't end here. With these new skills, you're well-equipped to experiment with more complex Python projects, explore other aspects of Python, and continue building a range of Python applications.

Have fun and happy coding!

Enjoyed building this Python project with me? Ready to dive deeper into Python? Check out:

Our Python Masterclass - Python with Dr. Johns

By Robert Johns

Technical Editor for Hackr.io | 15+ Years in Python, Java, SQL, C++, C#, JavaScript, Ruby, PHP, .NET, MATLAB, HTML & CSS, and more... 10+ Years in Networking, Cloud, APIs, Linux | 5+ Years in Data Science | 2x PhDs in Structural & Blast Engineering

View all post by the author

Learn More

Please login to leave comments