C++ Hangman Game Project
Guess the hidden word letter by letter before the drawing completes.
What you will build
The program picks a word from a file, shows blanks, and you guess letters — each miss adds a body part to the gallows. It's a string-manipulation workout: tracking guessed letters, revealing matches, and rendering state from data.
What you will learn
- Loading a word list from a file
- Tracking state with std::set
- Building a display string from game state
- Input validation (single, unguessed letter)
Feature checklist
- Random word from a word-list file
- Blanks fill in as letters are guessed
- ASCII gallows that grows with each miss
- 6–7 misses allowed
- Guessed letters shown so you don't repeat them
- Win/lose message revealing the word
Starter code
#include <iostream>
#include <fstream>
#include <set>
#include <string>
#include <random>
std::string pickWord(const std::string& path) {
std::ifstream in(path);
std::vector<std::string> words; std::string w;
while (in >> w) words.push_back(w);
std::mt19937 rng(std::random_device{}());
return words[std::uniform_int_distribution<size_t>(0, words.size() - 1)(rng)];
}
int main() {
std::string word = pickWord("words.txt");
std::set<char> guessed;
int misses = 0;
while (misses < 7) {
bool complete = true;
for (char c : word) {
if (guessed.count(c)) std::cout << c << ' ';
else { std::cout << "_ "; complete = false; }
}
if (complete) { std::cout << "\nYou saved them!\n"; return 0; }
std::cout << "\nGuess a letter: ";
char g; std::cin >> g;
guessed.insert(std::tolower(g));
if (word.find(std::tolower(g)) == std::string::npos) ++misses;
}
std::cout << "Out of guesses. The word was: " << word << "\n";
}Full walkthrough
Step 1: Load a word list and pick with pickWord()
pickWord() reads words.txt (one word per line) into a vector with std::ifstream and std::getline, then returns one chosen by std::uniform_int_distribution over the indexes, using the mt19937 + random_device pairing you know. If the file is missing, fall back to a small built-in list and SAY so — a silent missing-file crash helps nobody.
Step 2: Track the game state with a set of guesses
State: the secret word, a std::set<char> guessed (a set because membership tests — 'already tried B?' — are the operation you perform constantly, and duplicates are impossible by construction), and misses remaining (6 or 7). The displayed word is DERIVED: each letter shows if it is in guessed, else '_'.
Step 3: Draw the gallows by miss count
A function taking misses-so-far prints one of 7 ASCII stages stored as an array of strings — stage 0 is the empty gallows, each miss adds head, body, an arm, a leg. Indexing an array of pictures by a counter is simpler and far less error-prone than assembling body parts with ifs.
const char* stages[7] = { stage0, stage1, /* ... */ stage6 };
std::cout << stages[missesUsed];Step 4: Run the guess loop
While misses remain and the word is not fully revealed: draw the gallows, the masked word, and the guessed letters; read a char; lowercase it; if it is already in guessed, say so WITHOUT charging a miss; insert it; if the word does not contain it, charge a miss. The 'repeat guesses are free' rule is a fairness decision the checklist implies by asking for guessed letters to be shown.
Step 5: Detect the win from the derived word
After each guess, build the masked word; if it contains no '_', the player wins. Deriving win/lose from the same function that draws the word means the display and the verdict can never disagree — one source of truth again.
Step 6: End honestly: reveal the word either way
Win: 'You win! The word was BANANA.' Lose, when misses run out: draw the final gallows stage and 'Out of tries — the word was BANANA.' Revealing on a loss is in the checklist and in every good implementation: players who never learn the word feel cheated, not challenged.
Step 7: Test the edges of the alphabet
Guess a letter not in the word (miss charged, gallows advances one stage), a correct letter (ALL its positions reveal at once — check BANANA's three A's), the same wrong letter twice (charged once), and an uppercase letter (counts as its lowercase). Then win a game and lose a game deliberately.
Common mistakes
- Revealing only the FIRST occurrence of a guessed letter, so BANANA shows '_A____' and the player can never finish.
- Charging a miss for a repeated guess, punishing the player for your missing membership check.
- Uppercase input silently missing lowercase words because the comparison never normalised case.
Compile and run
g++ -std=c++17 -o hangman hangman.cppSample run
$ ./hangman
Welcome to Hangman! The word has 6 letters.
Word: _ _ _ _ _ _
Guess a letter:
> a
Word: _ A _ A _ A
Guess a letter:
> e
No E in the word — the gallows grows a head:
+---+
| |
O |
|
|
===
> n
Word: _ A N A N A
> b
Word: B A N A N A
You win! The word was BANANA — with 5 misses to spare.Try it in your browser
No browser demo is included for this project. Build the C++ version below — that is the real program.