Hangman Game with a GUI in Python
In this article, we’ll be building the Hangman Game. To create the game’s graphical user interface (GUI), we’ll be using the Pygame library in Python. Pygame is a library commonly used for making graphical user interface games. So, let’s dive into creating our Hangman Game with the help of Pygame!
What is the Hangman Game?
Hangman is a word-guessing game where one player thinks of a word and the other player tries to guess it by suggesting letters. A blank line is drawn for each letter in the word, and the player fills in the blanks with correct guesses. However, for each incorrect guess, a part of a “hangman” figure is drawn. The goal is to guess the word before the hangman is fully drawn.
Hangman Game with a GUI in Python
Below, are the step-by-step implementation of the Hangman Game with a GUI in Python.
Create a Virtual Environment
First, create the virtual environment using the below commands
python -m venv env
.\env\Scripts\activate.ps1
Install Necessary Library
As we are going to work with Pygame, it is mandatory to have the Pygame library installed in your IDE. For install the Pygame use the below command.
pip3 install pygame
Implement the Logic
Here, we implement the logic step-by-step.
Step 1: Initialize Pygame & Set up Game Window
In below code, Pygame is initialized, the dimensions of the game window are set, and the window is created. The window title is set to “HANGMAN,” and the frames per second (FPS) are established. The clock is created to control the frame rate, and the run
variable is set to True
to start the game loop.
Python3
import pygame import math import random pygame.init() WIDTH, HEIGHT = 1000 , 700 win = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption( "HANGMAN" ) FPS = 60 clock = pygame.time.Clock() run = True |
Step 2: Set up Buttons for Letters
Below code creates a grid of alphabet buttons with a radius of 24 pixels, spaced 20 pixels apart. Button coordinates and letters are stored in the ‘letters’ list, using ASCII values. The loop calculates x, y coordinates for each button and appends them to the list with the letter and an initial state of True.
Python3
# Buttons radius = 24 space = 20 letters = [] # [399, 122, "A", True] x_start = round ((WIDTH - (radius * 2 + space) * 13 ) / 2 ) y_start = 540 A = 65 # Using ASCII value to print letters on the button. A->65, B->66, and so on for i in range ( 26 ): x = x_start + space * 2 + ((radius * 2 + space) * (i % 13 )) y = y_start + ((i / / 13 ) * (space + radius * 2 )) letters.append([x, y, chr (A + i), True ]) |
Step 3: Define Fonts & Load Hangman Images
Below code defines three fonts (“comicsans” with sizes 45, 40, and 70) using pygame’s SysFont. It then loads a series of hangman images (“man1.png” to “man7.png”) into a list called ‘images’. The list is printed to the console.
Python3
# Fonts font = pygame.font.SysFont( "comicsans" , 45 ) WORD = pygame.font.SysFont( "comicsans" , 40 ) TITLE = pygame.font.SysFont( "comicsans" , 70 ) # Time to load images so we can draw a hangman images = [] for i in range ( 0 , 7 ): image = pygame.image.load( "man" + str (i + 1 ) + ".png" ) images.append(image) print (images) |
Step 4: Initialize Game Variables & Draw Function
Below, code initializes game variables, including the target word randomly chosen from a list. The ‘draw’ function is defined to render the game interface, displaying the hangman title, the current state of the word (with guessed letters filled in), alphabet buttons, and hangman images. The display is updated using pygame, and the hangman images are based on the ‘hangman’ variable.
Python3
# Game variables hangman = 0 lists = [ "Beginner" , "GFG" , "DOCKER" , "DEVELOPER" , "RUST" , "GITHUB" , "R" , "PYTHON" , "BASH" ] words = random.choice(lists) guessed = [] # to track the letters we have guessed # Function to draw buttons, and hangman def draw(): win.fill(( 255 , 255 , 255 )) # Display with white color # Title for the game # Updated title for better visibility title = TITLE.render( "Hangman" , 1 , ( 0 , 0 , 0 )) # Title in center and then y-axis= 24 win.blit(title, (WIDTH / 1.7 - title.get_width() / 2 , 10 )) # Draw word on the screen disp_word = "" for letter in words: if letter in guessed: disp_word + = letter + " " else : disp_word + = "_ " text = WORD.render(disp_word, 1 , ( 0 , 0 , 0 )) win.blit(text, ( 500 , 250 )) # Buttons at center for btn_pos in letters: # Making button visible and invisible after clicking it x, y, ltr, visible = btn_pos if visible: pygame.draw.circle(win, ( 0 , 0 , 0 ), (x, y), radius, 4 ) txt = font.render(ltr, 1 , ( 0 , 0 , 0 )) win.blit(txt, (x - txt.get_width() / 2 , y - txt.get_height() / 2 )) win.blit(images[hangman], ( 50 , 50 )) pygame.display.update() |
Step 5: Handle User Input & Check Win/Loss Conditions
Below, code runs a hangman game loop using Pygame. It includes event handling for mouse clicks to guess letters, checks if the guessed word matches the target word, and updates the game state accordingly. If the player wins, a victory message is displayed, and if the player loses (hangman reaches its maximum state), a defeat message along with the correct answer is shown.
Python3
while run: clock.tick(FPS) draw() for event in pygame.event.get(): # Triggering the event if event. type = = pygame.QUIT: run = False if event. type = = pygame.MOUSEBUTTONDOWN: x_mouse, y_mouse = pygame.mouse.get_pos() for letter in letters: x, y, ltr, visible = letter if visible: # To handle collision and to click the button exactly in the circle dist = math.sqrt((x - x_mouse) * * 2 + (y - y_mouse) * * 2 ) if dist < = radius: letter[ 3 ] = False # To invisible the clicked button guessed.append(ltr) if ltr not in words: hangman + = 1 # Deciding if you won the game or not won = True for letter in words: if letter not in guessed: won = False break if won: draw() pygame.time.delay( 1000 ) win.fill(( 0 , 0 , 0 )) text = WORD.render( "YOU WON" , 1 , ( 129 , 255 , 0 )) win.blit(text, (WIDTH / 2 - text.get_width() / 2 , HEIGHT / 2 - text.get_height() / 2 )) pygame.display.update() pygame.time.delay( 4000 ) print ( "WON" ) break if hangman = = 6 : draw() pygame.time.delay( 1000 ) win.fill(( 0 , 0 , 0 )) text = WORD.render( "YOU LOST" , 1 , ( 255 , 0 , 5 )) answer = WORD.render( "The answer is " + words, 1 , ( 129 , 255 , 0 )) win.blit(text, (WIDTH / 2 - text.get_width() / 2 , HEIGHT / 2 - text.get_height() / 2 )) win.blit(answer, ((WIDTH / 2 - answer.get_width() / 2 ), (HEIGHT / 2 - text.get_height() / 2 ) + 70 )) pygame.display.update() pygame.time.delay( 4000 ) print ( "LOST" ) break pygame.quit() |
Complete Code
Python3
import pygame #GUI using pygame import math import random pygame.init() WIDTH, HEIGHT = 1000 , 700 win = pygame.display.set_mode((WIDTH,HEIGHT)) pygame.display.set_caption( "HANGMAN" ) FPS = 60 clock = pygame.time.Clock() run = True #buttons radius = 24 space = 20 letters = [] #[399,122,"A",True] x_start = round ((WIDTH - (radius * 2 + space) * 13 ) / 2 ) y_start = 540 A = 65 # Using ACII value to print letters on the button. A->65, B->66 and so on for i in range ( 26 ): x = x_start + space * 2 + ((radius * 2 + space) * (i % 13 )) y = y_start + ((i / / 13 ) * (space + radius * 2 )) letters.append([x,y, chr (A + i), True ]) # Fonts font = pygame.font.SysFont( "comicsans" , 45 ) WORD = pygame.font.SysFont( "comicsans" , 40 ) TITLE = pygame.font.SysFont( "comicsans" , 70 ) # Time to load images so we can draw a hangman images = [] for i in range ( 0 , 7 ): image = pygame.image.load( "man" + str (i + 1 ) + ".png" ) images.append(image) print (images) # game variable hangman = 0 lists = [ "Beginner" , "GFG" , "DOCKER" , "DEVELOPER" , "RUST" , "GITHUB" , "R" , "PYTHON" , "BASH" ] words = random.choice(lists) guessed = [] # to track the letters we have guessed # function to draw buttons, and hangman def draw(): win.fill(( 255 , 255 , 255 )) # display with white color # TITLE for the game title = TITLE.render( "HangMan" , 1 ,( 0 , 0 , 0 , 0 )) win.blit(title,(WIDTH / 1.9 - title.get_width() / 2 , 10 )) # Title in center and then y axis= 24 # draw word on the screen disp_word = "" for letter in words: if letter in guessed: disp_word + = letter + " " else : disp_word + = "_ " text = WORD.render(disp_word, 1 ,( 0 , 0 , 0 , 0 )) win.blit(text,( 500 , 250 )) #buttons at center for btn_pos in letters: x,y,ltr,visible = btn_pos # making button visible and invisible after clikcing it if visible: pygame.draw.circle(win,( 0 , 0 , 0 , 0 ),(x,y),radius, 4 ) txt = font.render(ltr, 1 ,( 0 , 0 , 0 , 0 )) win.blit(txt,(x - txt.get_width() / 2 ,y - txt.get_height() / 2 )) win.blit(images[hangman], ( 50 , 50 )) pygame.display.update() while run: clock.tick(FPS) draw() for event in pygame.event.get(): # Triggering the event if event. type = = pygame.QUIT: run = False if event. type = = pygame.MOUSEBUTTONDOWN: x_mouse, y_mouse = pygame.mouse.get_pos() #print(pos) for letter in letters: x,y,ltr,visible = letter if visible: dist = math.sqrt((x - x_mouse) * * 2 + (y - y_mouse) * * 2 ) if dist< = radius: letter[ 3 ] = False #to invisible the clicked button guessed.append(ltr) if ltr not in words: hangman + = 1 # -------------------------------------------------------------------------------- # deciding if you won the game or not won = True for letter in words: if letter not in guessed: won = False break if won: draw() pygame.time.delay( 1000 ) win.fill(( 0 , 0 , 0 , 0 )) text = WORD.render( "YOU WON" , 1 ,( 129 , 255 , 0 , 255 )) win.blit(text,(WIDTH / 2 - text.get_width() / 2 , HEIGHT / 2 - text.get_height() / 2 )) pygame.display.update() pygame.time.delay( 4000 ) print ( "WON" ) break if hangman = = 6 : draw() pygame.time.delay( 1000 ) win.fill(( 0 , 0 , 0 , 0 )) text = WORD.render( "YOU LOST" , 1 , ( 255 , 0 , 5 , 255 )) answer = WORD.render( "The answer is " + words, 1 ,( 129 , 255 , 0 , 0 )) win.blit(text, (WIDTH / 2 - text.get_width() / 2 , HEIGHT / 2 - text.get_height() / 2 )) win.blit(answer, ((WIDTH / 2 - answer.get_width() / 2 ), (HEIGHT / 2 - text.get_height() / 2 ) + 70 )) pygame.display.update() pygame.time.delay( 4000 ) print ( "LOST" ) break pygame.quit() |
Output :
Video Demonstration
Conclusion
In conclusion, the Hangman Game implemented with a graphical user interface (GUI) in Python using the Pygame library provides an engaging and interactive experience. Players can guess letters by clicking on buttons, with the game visually representing their progress and any incorrect guesses through a hangman figure. The code combines Python’s simplicity with Pygame’s capabilities to create a visually appealing and playable version of the classic word-guessing game.