Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
Table of contents:
- Introduction: Hangman Rules
- Step 1: Loading the Words Into Our Program
- Step 2: Implementing the Hangman Game in C++
- Step 3: Testing our Implementation
- Conclusion
Reading time: 20 minutes
Introduction: Hangman Rules
In this article at OpenGenus, we will cover how to create a console hangman game in C++ programming language. Hangman is a popular word-guessing game that involves one player picking a random word, providing the number of letters in that word, and having the other player guess a letter that could be in the word. The mystery word is typically represented by a series of underscores that represent the letters in the word.
The rules for hangman are as follows:
- The player receives 6 attempts.
- Each time the player guesses a letter incorrectly, they lose an attempt and a part of the hangman figure is drawn.
- If the player guesses an incorrect letter 6 times, they have lost the game and the hangman figure is complete.
- If the player is able to guess the word correctly without 6 incorrect attempts, they win the game.
Step 1: Loading the Words Into Our Program
To provide the user with a word to guess, we must provide a list of words to choose from. Our program will pick one at random and display the number of letters to the user. We will create a text file called "word.txt" that contains a list of words, one on each row. To load the words contained in the file into our program, we can utilize the ifstream package in C++. This package allows us to read data from a file:
#include <fstream>
using namespace std;
vector<string> words; // Initialize vector of words we will use in our hangman game
string word;
ifstream inputFile("words.txt"); // Read from input word file
while (getline(inputFile, word)) {
if (!word.empty() && word[word.size() - 1] == '\r') { // Remove endline "\n" of each word
word = word.substr(0, word.size() - 1);
}
words.push_back(word); // Then, insert each word into our vector of words
}
inputFile.close(); // Close input file
Step 2: Implementing the Hangman Game in C++
Now that we've provided our program with a list of words to choose from, we can begin implementing our hangman game. There are a couple of things we must implement to get the game working properly.
First, we must create a function that determines whether or not the user has won the game. If the number of letters correctly guessed is equal to the length of the special word, this means the player has won. Otherwise, all letters have not been guessed correctly and the player has not won:
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <fstream>
#include <cstdlib>
using namespace std;
// Check if the player has won the game
bool isCorrectGuess(const string &secretWord, const vector<bool> &guessedLetters) {
for (size_t i = 0; i < secretWord.size(); ++i) {
if (!guessedLetters[i]) { // If the number of guessed letters != the number of letters in the secret word,
return false; // Return false. The player has not won the game
}
}
return true; // Otherwise, return true. The player has won the game
}
Next, we must ensure that a random word is chosen each time. To make the game more fun and exciting, we should decrease the number of repeats:
srand(static_cast<unsigned int>(time(nullptr))); // Seed the random number generator with the current time,
string secretWord = words[rand() % words.size()]; // Then use that number to pick a word at random
It is essential to determine if a letter guessed by the user exists in the hidden word. We can do this by initializing a vector of bools the size of the secret word. Each letter will have an initialized value of false. When a letter in the word is guessed correctly, the bool value would change to true. As a result, this would be displayed to the user:
vector<bool> guessedLetters(secretWord.size(), false);
int attemptsLeft = 6; // Initialize the number of attempts given to a user
cout << "Hangman Game" << endl;
while (attemptsLeft > 0) { // While, the user has remaining attempts
// Display the word with underscores for unguessed letters
cout << "Secret Word: ";
for (size_t i = 0; i < secretWord.size(); ++i) {
if (guessedLetters[i]) {
cout << secretWord[i] << " "; // If letter is guessed correctly, display the letter
} else {
cout << "_ "; // Otherwise, display letters as a series of underscores
}
}
cout << endl;
char inputChar;
cout << "Guess a letter: "; // User provides a letter as input
cin >> inputChar;
bool letterFound = false;
for (size_t i = 0; i < secretWord.size(); ++i) {
if (secretWord[i] == inputChar) { // Check if the letter is part of the word
guessedLetters[i] = true;
letterFound = true;
}
}
We will also include an implementation that displays if the user's provided guess was correct or incorrect as well as keeping track of the number of attempts they have left. If they correctly guess all the letters, it will display that the user has won. If the user guessed incorrectly and has zero attempts left, it will display that the user has lost the game:
if (!letterFound) {
--attemptsLeft; // If the guess is incorrect, decrease the number of attempts by 1
cout << "Incorrect guess. Attempts left: " << attemptsLeft << endl;
}
if (isCorrectGuess(secretWord, guessedLetters)) { // If the user has correctly guessed the entire word, they have won the game
cout << "Congratulations! You have won the game. The word was:" << secretWord << endl;
break;
}
}
if (attemptsLeft <= 0) { // If the user has no attempts remaining,
cout << "Game Over! The word was: " << secretWord << endl; // Game over. The user has lost the game
}
Lastly, we will create a function that will draw the hangman figured based on the number of incorrect guesses provided by the user:
// Draw the Hangman figure based on the number of incorrect guesses
void drawHangman(int incorrectGuesses) {
if (incorrectGuesses == 0){
cout << " ________" << endl;
cout << " | |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 1) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 2) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 3) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | /|" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 4) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | /|\\" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 5) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | /|\\" << endl;
cout << " | / " << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | /|\\" << endl;
cout << " | / \\" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
}
Step 3: Testing our Implementation
To test our code, we must navigate to the correct directory where our file is located and compile. This can be done using Terminal, Command Prompt, Ubuntu, etc. To run my code, I used Ubuntu and ran the following command:
g++ hangman.cpp -o hangman
Once our code is compiled, we can run our code using:
./hangman
When run successfully, you will get an output that looks similar to the following:
Hangman Game
Secret Word: _ _ _ _ _ _
Guess a letter:
Here is an example of what the game looks like when the secret word is correctly guessed:
Hangman Game
Secret Word: _ _ _ _ _ _ _ _ _
Guess a letter: a
Secret Word: _ _ _ _ a _ _ _ _
Guess a letter: r
Secret Word: _ _ _ r a _ _ _ _
Guess a letter: i
Secret Word: i _ _ r a _ i _ _
Guess a letter: t
Secret Word: i t _ r a t i _ _
Guess a letter: e
Secret Word: i t e r a t i _ _
Guess a letter: o
Secret Word: i t e r a t i o _
Guess a letter: n
Congratulations! You guessed the word: iteration
Conclusion
Overall, using a text-based method is the simplest way to create a hangman game in C++. But, there are certainly other methods that could be utilized such as:
- GUI (Graphical User Interface): A GUI allows the user to interact with graphical elements such as buttons or icons, making the game more visually appealing and complex.
- OOP (Object-Oriented Programming): A class-based hangman game could be utilized in the scenario that the game becomes more complex or there are different versions of the game. Instead of rewriting code for each version, utilizing classes would make the code much more efficient, neater, and easier to maintain.
Here is the complete C++ code for our hangman game:
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <fstream>
#include <cstdlib>
using namespace std;
// Check if player has won the game
bool isCorrectGuess(const string &secretWord, const vector<bool> &guessedLetters) {
for (size_t i = 0; i < secretWord.size(); ++i) {
if (!guessedLetters[i]) { // If the number of guessed letters != the number of letters in the secret word,
return false; // Return false. The player has not won the game
}
}
return true; // Otherwise, return true. The player has won the game
}
// Draw the Hangman figure based on the number of incorrect guesses
void drawHangman(int incorrectGuesses) {
if (incorrectGuesses == 0){
cout << " ________" << endl;
cout << " | |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 1) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 2) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | |" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 3) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | /|" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 4) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | /|\\" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else if (incorrectGuesses == 5) {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | /|\\" << endl;
cout << " | / " << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
else {
cout << " ________" << endl;
cout << " | |" << endl;
cout << " | O" << endl;
cout << " | /|\\" << endl;
cout << " | / \\" << endl;
cout << " |" << endl;
cout << "_|________" << endl;
}
}
int main() {
vector<string> words; // Initialize vector of words we will use in our hangman game
string word;
ifstream inputFile("words.txt"); // Read from input word file
while (getline(inputFile, word)) {
if (!word.empty() && word[word.size() - 1] == '\r') { // Remove endline "\n" of each word
word = word.substr(0, word.size() - 1);
}
words.push_back(word); // Then, insert each word into our vector of words
}
inputFile.close(); // Close input file
srand(static_cast<unsigned int>(time(nullptr))); // Seed the random number generator with the current time,
string secretWord = words[rand() % words.size()]; // Then use that number to pick a word at random
vector<bool> guessedLetters(secretWord.size(), false);
int attemptsLeft = 6; // Initialize the number of attempts given to a user
cout << "Hangman Game" << endl;
while (attemptsLeft > 0) { // While, the user has remaining attempts
// Display the word with underscores for unguessed letters
cout << "Secret Word: ";
for (size_t i = 0; i < secretWord.size(); ++i) {
if (guessedLetters[i]) {
cout << secretWord[i] << " "; // If letter is guessed correctly, display the letter
} else {
cout << "_ "; // Otherwise, display letters as a series of underscores
}
}
cout << endl;
char inputChar;
cout << "Guess a letter: "; // User provides a letter as input
cin >> inputChar;
bool letterFound = false;
for (size_t i = 0; i < secretWord.size(); ++i) { // Check if the letter is part of the word
if (secretWord[i] == inputChar) {
guessedLetters[i] = true;
letterFound = true;
}
}
if (!letterFound) {
--attemptsLeft; // If guess is incorrect, decrease the number of attempts by 1
cout << "Incorrect guess. Attempts left: " << attemptsLeft << endl;
}
drawHangman(6 - attemptsLeft);
if (isCorrectGuess(secretWord, guessedLetters)) { // If user has correctly guessed the entire word, they have won the game
cout << "Congratulations! You have won the game. The word was:" << secretWord << endl;
break;
}
}
if (attemptsLeft <= 0) { // If the user has no attempts remaining,
cout << "Game Over! The word was: " << secretWord << endl; // Game over. The user has lost the game
}
return 0;
}