Open In App

Hangman Game with a GUI in Python

Last Updated : 20 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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 = ["GEEKS", "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=["GEEKS","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 :

dfjng

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.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads