A simple command-line Hangman game built with Python.
This project is part of my Python learning journey and focuses on applying programming fundamentals through a complete game project.
The goal is to build a command-line version of the classic Hangman game.
The game randomly selects a word, and the player has to guess the word one letter at a time.
For every incorrect guess, the player loses a life and another part of the Hangman is drawn.
The goal is to guess all the letters in the word before running out of lives.
Instead of trying to build the entire game at once, I broke the problem down into smaller, manageable steps.
The development process started with understanding the game logic and designing the program flow before implementing each part.
The first step was to understand the rules and define what the final program should do.
The game needs to:
- Generate a random word
- Hide the letters from the player
- Allow the player to guess one letter at a time
- Reveal correctly guessed letters
- Remove a life for incorrect guesses
- Draw the Hangman as lives are lost
- Detect when the player wins
- Detect when the player runs out of lives
Before writing code, I broke the game into smaller problems and mapped the program logic using a flowchart.
The program follows this general flow:
- Generate a random word.
- Create a hidden representation of the word using blanks.
- Ask the player to guess a letter.
- Check whether the guessed letter exists in the word.
- If the guess is correct:
- Reveal the corresponding letter(s).
- Check whether all letters have been guessed.
- If the guess is incorrect:
- Remove one life.
- Add the next stage of the Hangman drawing.
- Check whether the player has run out of lives.
- If all letters are revealed, the player wins.
- If all lives are lost, the player loses.
- Otherwise, continue asking for another guess.
I created a flowchart to visualize the complete logic of the game before starting the implementation.
The flowchart acts as the blueprint for the implementation and helps keep the different game states and exit conditions clear.
The first implementation step focused on selecting a random word and checking the player's guess.
The game needs a word for the player to guess.
Instead of selecting the word manually, I used Python's random module to randomly select one word from a predefined list.
The selected word is stored in a variable called chosen_word.
The program asks the player to enter a letter.
The input is converted to lowercase so that uppercase and lowercase guesses are handled consistently.
For example:
Guess a letter: A
becomes:
a
This makes comparisons easier because the words in the word list are also stored in lowercase.
The program loops through each character of the selected word and compares it with the player's guess.
For each character:
- If the letters match โ
Right - If they don't match โ
Wrong
For example, if the selected word is:
camel
and the player guesses:
a
the program checks each character:
c โ Wrong
a โ Right
m โ Wrong
e โ Wrong
l โ Wrong
- Importing modules
random.choice()- Variables
input().lower()forloops- Iterating through strings
if / elsestatements- String comparison
The next challenge was to move from simply checking whether a guessed letter exists to actually displaying the current state of the word.
The player should not see the original word. Instead, they should see a series of blanks representing the letters they still need to guess.
First, I created a placeholder containing one underscore for every character in the chosen word.
For example:
apple
becomes:
_ _ _ _ _
The number of blanks is determined dynamically based on the length of the selected word.
The next step was to replace the appropriate blanks with letters that the player has guessed correctly.
For example, if the selected word is:
apple
and the player guesses:
p
the display becomes:
_ p p _ _
The program loops through each letter of the chosen word:
- If the current letter matches the guess โ add the letter
- Otherwise โ add
_
This creates a new string representing the current state of the word.
len()range()forloops- Strings
- String concatenation with
+= - Conditional statements
- Building strings dynamically
This step demonstrated how to build a new string step by step based on another string instead of modifying the original word.
At this stage, the game becomes interactive and allows the player to keep guessing until the word has been completely revealed.
The main challenges were:
- Allowing multiple guesses
- Keeping previously correct guesses
- Detecting when all letters have been guessed
- Knowing when the game should stop
The previous version only allowed one guess.
To allow the player to continue guessing, I introduced a while loop.
The loop continues while the game is not over.
A game_over variable controls when the loop should stop.
Initially:
game_over = False
Once all letters have been guessed:
game_over = True
The display string contains underscores for letters that have not been guessed.
If there are no underscores left in display, all letters have been revealed and the player wins.
Conceptually:
Are there any "_" characters left?
โ
โโโ Yes โโโ Continue playing
โ
โโโ No โโโโ You Win ๐
A problem appeared when the player made multiple correct guesses.
Each new guess rebuilt the display string and caused previous correct guesses to disappear.
To solve this, I created a list called correct_letters.
Whenever the player correctly guesses a letter, that letter is added to the list.
The list is created outside the while loop so that its contents persist between guesses.
When rebuilding the display, the program checks:
- Is the current letter equal to the player's current guess?
- Has the current letter already been added to
correct_letters?
If either condition is true, the letter is revealed.
Otherwise, an underscore is displayed.
This step introduced an important programming concept:
Maintaining state between iterations of a loop.
The correct_letters list acts as a persistent record of the player's progress.
whileloops- Boolean variables
True/Falseif / elif / else- The
inoperator - Lists
.append()- Maintaining state between loop iterations
- Loop exit conditions
- Building strings dynamically
The next step was to add the lives system and connect it to the Hangman ASCII art.
The player starts with 6 lives.
A variable called lives keeps track of the remaining lives.
lives = 6
Every incorrect guess removes one life.
6 โ 5 โ 4 โ 3 โ 2 โ 1 โ 0
When lives reach zero, the game ends and the player loses.
The program checks whether the guessed letter exists in the chosen word.
If the guessed letter is not present, the number of lives is reduced by one.
Conceptually:
Player makes a guess
โ
Is the letter in the word?
โโโ Yes โโโ Continue
โ
โโโ No โโโโ Lose 1 life
โ
Are lives = 0?
โโโ No โ Continue
โโโ Yes โ You Lose
After reducing the number of lives, the program checks whether the player has reached zero lives.
If:
lives == 0
the game is marked as over and the player receives a You lose. message.
The project contains several ASCII-art stages representing the Hangman at different points in the game.
The stages correspond to the number of remaining lives:
Lives: 6 โ No man
Lives: 5 โ First stage
Lives: 4 โ Second stage
Lives: 3 โ Third stage
Lives: 2 โ Fourth stage
Lives: 1 โ Fifth stage
Lives: 0 โ Complete Hangman
Correct guesses do not change the Hangman.
Incorrect guesses reduce lives and display the corresponding Hangman stage.
- Variables
- Integers
- Arithmetic operators
-=ifstatements- The
not inoperator - Boolean game states
- Lists
- List indexing
- ASCII art
- Combining program logic with visual output
The final step focused on improving the structure of the project and making the game easier and more enjoyable to use.
The main goals were:
- Separate data from the main game logic
- Practice importing custom modules
- Give the user better feedback
- Handle repeated guesses
- Show the remaining lives
- Improve the win and lose messages
- Add a visual game logo
Instead of keeping the word list directly inside main.py, I moved it into a separate module called hangman_words.py.
The word list can then be imported into the main program.
This separates the game logic from the data and makes the project structure cleaner.
The Hangman stages were moved into a separate module called hangman_art.py.
This module contains:
- The Hangman stages
- The game logo
The main program imports the required elements instead of keeping all of the ASCII art inside main.py.
This makes the main game logic easier to read and maintain.
This step provided practical experience with Python modules and different import styles.
For example, a module can be imported directly:
import hangman_words
Or specific objects can be imported from a module:
from hangman_words import word_list
Using separate modules helps keep larger programs organized and makes individual components easier to manage.
The game now checks whether the player has already guessed a letter.
If the letter is already inside correct_letters, the user receives feedback such as:
You already guessed a
The player does not lose a life for repeating a correct guess.
This makes the game fairer and provides clearer feedback.
When the player guesses a letter that does not exist in the chosen word, the program tells them exactly what happened.
For example:
You guessed d, that's not in the word. You lose a life.
This improves the user experience by making the result of each action clear.
The game now tells the player how many lives they have remaining.
For example:
4 / 6 lives left
This gives the player a clear indication of their current game state and how close they are to losing.
If the player loses the game, the program reveals the word they were trying to guess.
For example:
The word was: python
This prevents the game from ending without explaining the correct answer.
The Hangman logo is stored in hangman_art.py and displayed when the game starts.
This gives the command-line application a more polished appearance.
The final step showed that building a program is not only about making the core functionality work.
After the main logic was complete, I improved:
- Code organization
- User feedback
- Readability
- Maintainability
- User experience
This is an important part of software development because a working program can still be improved significantly.
- Creating custom modules
importfrom ... import ...- Separating data from logic
- Lists
- Conditional logic
- F-strings
- User feedback
- State management
- Code organization
- User experience considerations
After completing all five steps, the overall game flow is:
Start Game
โ
Display Hangman Logo
โ
Select Random Word
โ
Create Hidden Word
โ
Player Makes a Guess
โ
Has The Letter Been Guessed Before?
โโโ Yes โ Inform User
โ
โโโ No
โ
Is Letter In The Word?
โโโ Yes โ Reveal Letter
โ
โโโ No โ Lose One Life
โ
Display Hangman Stage
โ
Are All Letters Revealed?
โโโ Yes โ You Win ๐
โ
โโโ No
โ
Are There Any Lives Left?
โโโ Yes โ Continue
โ
โโโ No โ You Lose ๐
โ
Reveal Word
โ
End Game
Throughout the project, I practiced:
- Variables and data types
- User input
if / elif / elseforloopswhileloops- Lists
- Strings
len()range()- Modules
- Custom modules
importfrom ... import ...random.choice()- String concatenation
.append()- Boolean values
- The
inoperator - The
not inoperator - List indexing
- F-strings
- ASCII art
- Program flow
- Conditional logic
- Maintaining state
- Problem decomposition
- Code organization
- User experience
โ Completed
The Hangman game has now been implemented through five development stages.
- Understand the game requirements
- Break down the problem
- Create the game flowchart
- Select a random word
- Get and normalize the player's guess
- Check whether the guessed letter exists in the word
- Create placeholders for the hidden word
- Reveal correctly guessed letters
- Allow the player to make multiple guesses
- Keep track of previously correct guesses
- Implement the win condition
- Add a game-over state
- Implement the lives system
- Reduce lives after incorrect guesses
- Implement the lose condition
- Display Hangman stages based on remaining lives
- Separate the word list into a custom module
- Separate the Hangman art into a custom module
- Add the Hangman logo
- Handle repeated guesses
- Improve feedback for incorrect guesses
- Display remaining lives
- Reveal the correct word when the player loses
- Improve overall user experience
python-hangman/
โ
โโโ assets/
โ โโโ hangman-flowchart.pdf
โ
โโโ hangman_art.py
โโโ hangman_words.py
โโโ main.py
โโโ README.md
โโโ .gitignore
The main goal of this project was not only to create a working game, but to practice a structured approach to problem solving:
Understand โ Break Down โ Design โ Implement โ Test โ Improve
This project helped me practice turning a larger problem into smaller tasks, implementing each part individually, testing the result, and finally improving the code structure and user experience.
Although the core game is complete, there are still many ways it could be improved.
Possible future ideas include:
- Preventing invalid inputs
- Supporting full-word guesses
- Adding difficulty levels
- Keeping score
- Adding multiple rounds
- Adding a replay option
- Improving the command-line interface
- Adding colors to the terminal
- Creating a graphical user interface
- Adding unit tests
- Improving input validation
These improvements could be added later as additional exercises.
This project is part of my journey to become a more versatile software developer by expanding my Python skills and practicing problem solving through hands-on projects.
The focus of this project is not simply the final game, but the process of understanding a problem, breaking it down, implementing it step by step, and improving the final result.