Terminal Games
Simple games that run in the terminal.
Loading...
Searching...
No Matches
Hangman.cpp
1#include <algorithm>
2#include <cctype>
3#include <chrono>
4#include <cstdint>
5#include <iostream>
6#include <iterator>
7#include <regex>
8#include <string>
9#include <thread>
10#include <vector>
11
12#include "helpers/Globals.hpp"
13#include "helpers/PageBuilder.hpp"
14#include "helpers/Terminal.hpp"
15
16#include "games/Hangman.hpp"
17
18namespace TerminalGames
19{
20 Hangman::Hangman(const bool& p_useAnsiEscapeCodes) :
22 m_turnCount(0),
25 m_isGameOver(false),
27 {
28 m_pageBuilder.SetProperties(Pages::HANGMAN, p_useAnsiEscapeCodes);
29 m_randomNumberGenerator.seed(std::chrono::system_clock::now().time_since_epoch().count());
30 }
31
33 {
34 m_commandsRemaining = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
36 m_incorrectGuesses.clear();
39 m_turnCount = 0;
40 m_isGameOver = false;
41 }
42
79
81 {
82 m_gameInformation.m_hangmanGameInformation = {
83 .m_incorrectGuesses = m_incorrectGuesses,
84 .m_computerSpeedName = m_computerSpeedName,
85 .m_currentGuessOfWord = m_currentGuessOfWord,
86 .m_playerCount = m_playerCount,
87 .m_wordToBeGuessed = m_wordToBeGuessed,
88 .m_turnCount = m_turnCount,
89 .m_currentLetterSelected = m_currentLetterSelected,
90 .m_isGameOver = m_isGameOver,
91 };
92 }
93
95 {
97 {
98 m_isGameOver = true;
99 return m_isGameOver;
100 }
101
102 for (uint32_t i = 0; i < m_wordToBeGuessed.size(); i++)
103 {
105 {
106 return false;
107 }
108 }
109
110 m_isGameOver = true;
111 return m_isGameOver;
112 }
113
115
120
122 {
123 uint32_t keyPress = 0;
124 uint32_t currentSelection = 0;
125
126 while (true)
127 {
128 m_gameInformation.m_hangmanGameInformation.m_currentLetterSelected = m_commandsRemaining[currentSelection];
129
131
132 keyPress = Terminal::GetNextKeyPress();
133
134 switch (keyPress)
135 {
137 Terminal::GetUserChoiceFromQuitMenus(m_pageBuilder.GetQuitOptionSelectionPage());
138 continue;
139
142 return;
143
145 currentSelection == 0 ? currentSelection = m_commandsRemaining.size() - 1 : --currentSelection;
146 break;
147
149 currentSelection == (m_commandsRemaining.size() - 1) ? currentSelection = 0 : ++currentSelection;
150 break;
151
152 default:
153 {
155
156 if (COMMAND_FIND_LOCATION != m_commandsRemaining.end())
157 {
158 currentSelection = static_cast<uint32_t>(std::distance(m_commandsRemaining.begin(), COMMAND_FIND_LOCATION));
159 }
160 }
161 }
162 }
163 }
164
166 {
168
169 std::this_thread::sleep_until(std::chrono::system_clock::now() + std::chrono::seconds(m_computerSpeed));
170
171 const char COMPUTER_COMMAND = m_commandsRemaining[m_randomNumberGenerator() % m_commandsRemaining.size()];
172
173 ExecuteGeneralCommand(COMPUTER_COMMAND);
174 }
175
177 {
178 Terminal::GetUserChoiceFromGameOverMenu(m_pageBuilder.GetGameOverPage(m_gameInformation), m_pageBuilder.GetQuitOptionSelectionPage());
179 }
180
182 {
183 m_saveGameOptions = true;
184 }
185
187 {
188 m_saveGameOptions = false;
189 m_hasSavedGameOptions = false;
190 }
191
193 {
195
196 const std::vector<std::string> MENUS = m_pageBuilder.GetPlayerCountOptionSelectionGamePages(m_gameInformation);
197 const std::vector<std::string> QUIT_MENUS = m_pageBuilder.GetQuitOptionSelectionPage();
199 }
200
202 {
204
205 const std::vector<std::string> MENUS = m_pageBuilder.GetUserPlayerChoiceOptionSelectionGamePages(m_gameInformation);
206 const std::vector<std::string> QUIT_MENUS = m_pageBuilder.GetQuitOptionSelectionPage();
208 }
209
211 {
213
214 const std::vector<std::string> MENUS = m_pageBuilder.GetComputerSpeedOptionSelectionGamePages(m_gameInformation);
215 const std::vector<std::string> QUIT_MENUS = m_pageBuilder.GetQuitOptionSelectionPage();
218 }
219
221 {
223
224 std::string input;
225 input.reserve(Globals::G_HANGMAN_MAXIMUM_WORD_SIZE + 1);
226
227 while (true)
228 {
229 Terminal::PrintOutput(m_pageBuilder.GetPageWithMessage(m_gameInformation, "Please enter the word to be guessed:"));
230
232
233 std::getline(std::cin, input);
234
235 if (input[0] == Globals::G_TERMINAL_QUIT_KEY)
236 {
237 Terminal::GetUserChoiceFromQuitMenus(m_pageBuilder.GetQuitOptionSelectionPage());
238 continue;
239 }
240
242 {
243 continue;
244 }
245
246 std::ranges::transform(input.begin(), input.end(), input.begin(), ::toupper);
247
248 if (std::regex_match(input, std::regex("^[A-Z]+$")))
249 {
250 m_wordToBeGuessed = input;
251 return;
252 }
253 }
254 }
255
260
261 void Hangman::ExecuteGeneralCommand(const char& p_guess)
262 {
263 bool isGuessCorrect = false;
264
265 for (uint32_t i = 0; i < m_wordToBeGuessed.size(); i++)
266 {
267 if (m_wordToBeGuessed[i] == p_guess)
268 {
269 isGuessCorrect = true;
270 m_currentGuessOfWord[i] = p_guess;
271 }
272 }
273
274 if (!isGuessCorrect)
275 {
276 m_incorrectGuesses.push_back(p_guess);
277 }
278
280 m_turnCount++;
281 }
282}
void GetWordFromComputer()
Gets a random word, from the word list loaded during the setup, when the computer is the word setter.
Definition Hangman.cpp:256
void GetUserPlayerChoice()
Prompts the user to select which player the will be playing the game as (only supported if playing ag...
Definition Hangman.cpp:201
uint32_t m_turnCount
The number of turns that have occurred.
Definition Hangman.hpp:162
void ToggleCurrentPlayer() override
Change the current player to the other player.
Definition Hangman.cpp:114
void UpdateGameInformation() override
Updates GameInformation to match the current state of the game.
Definition Hangman.cpp:80
void ExecuteUserCommand() override
Prompt the user to enter their command for the current turn.
Definition Hangman.cpp:121
bool IsGameOver() override
Check whether the game is over.
Definition Hangman.cpp:94
void SetupGame() override
Clears and sets all member variables to their game start default.
Definition Hangman.cpp:32
Hangman(const bool &p_useAnsiEscapeCodes)
Constructs a new Hangman object.
Definition Hangman.cpp:20
void GameOver() override
Display the game over message and prompt the user whether they would like to play again or quit the g...
Definition Hangman.cpp:176
void ExecuteComputerCommand() override
Get a random command from the computer.
Definition Hangman.cpp:165
uint32_t m_computerSpeed
The computer speed determined by the amount of seconds the computer must wait before executing it's c...
Definition Hangman.hpp:157
std::string m_userPlayerChoice
The choice of whether the user has selected to be the guesser or word setter.
Definition Hangman.hpp:147
void GetUserOptions() override
Prompt the user for their choice on various game-related options.
Definition Hangman.cpp:43
PageBuilder m_pageBuilder
Used to build pages required by the game.
Definition Hangman.hpp:106
bool m_isGameOver
Whether the game is over (true) or not (false).
Definition Hangman.hpp:178
void GetComputerSpeed()
Prompts the user to select how the speed of the computer decision making (this does not affect the di...
Definition Hangman.cpp:210
void RestartGame() override
Update variables to allow for the game to be restarted with the same user options.
Definition Hangman.cpp:181
void ResetGame() override
Update variables to allow for the game to be reset and so the user will be asked for new options.
Definition Hangman.cpp:186
GameInformation m_gameInformation
Used to package up the current state of the game so it can be used by m_pageBuilder.
Definition Hangman.hpp:111
std::string m_playerCount
The count of the user selected number of players.
Definition Hangman.hpp:142
std::vector< char > m_commandsRemaining
The letters which remain to be guessed.
Definition Hangman.hpp:122
std::default_random_engine m_randomNumberGenerator
Used to randomly select the word to be guessed from Globals::G_HANGMAN_COMPUTER_WORDS when the comput...
Definition Hangman.hpp:117
bool m_hasSavedGameOptions
Whether the user has selected all the game options (true) or not/partially (false)....
Definition Hangman.hpp:173
std::string m_currentGuessOfWord
The current guess state of the word to be guessed from the perspective of the guesser.
Definition Hangman.hpp:137
std::vector< char > m_incorrectGuesses
The letters which were guessed by the guesser and are incorrect.
Definition Hangman.hpp:127
bool IsCurrentTurnUsers() override
Check whether the current turn should be executed by the user.
Definition Hangman.cpp:116
void GetWordFromUser()
Prompts the user to enter a word to be guessed (whether the word is actually a word is not checked) w...
Definition Hangman.cpp:220
bool m_saveGameOptions
Whether to save the user's currently selected game options (true) and restart the game or not (false)...
Definition Hangman.hpp:184
std::string m_computerSpeedName
The name of the user selected computer speed.
Definition Hangman.hpp:132
std::string m_wordToBeGuessed
The word to be guessed by the guesser.
Definition Hangman.hpp:152
void ExecuteGeneralCommand(const char &p_guess)
Checks the single-letter guess against the word, updates the current guess of the word and the error ...
Definition Hangman.cpp:261
void GetPlayerCount()
Prompts the user to select how many players will be playing the game.
Definition Hangman.cpp:192
char m_currentLetterSelected
The letter to display to the user to represent what their current selected guess is.
Definition Hangman.hpp:167
static void GetUserChoiceFromGameOverMenu(const std::string &p_gameOverPage, const std::vector< std::string > &p_quitOptionMenus)
Get the user choice whether to restart the game, reset the game or a choice from the GetUserChoiceFro...
Definition Terminal.cpp:311
static uint32_t GetNextKeyPress()
Wrapper for <Windows.h> API for the FlushConsoleInputBuffer() and _getch() functions.
Definition Terminal.cpp:429
static void PrintOutput(const std::string &p_output)
Clears and then prints to the terminal.
Definition Terminal.cpp:381
static uint32_t GetUserChoiceFromGameMenus(const std::vector< std::string > &p_menus, const std::vector< std::string > &p_quitOptionMenus)
Get the user choice from a list of game menus screens that are printed to the terminal.
Definition Terminal.cpp:83
static void SetCursorPosition(const int16_t &p_xCoord, const int16_t &p_yCoord)
Wrapper around the <Windows.h> API for the SetConsoleCursorPosition() function.
Definition Terminal.cpp:481
static void GetUserChoiceFromQuitMenus(const std::vector< std::string > &p_menus)
Gets the user choice from the quit menu. All user choices result in a different custom exception bein...
Definition Terminal.cpp:332
static const uint32_t G_HANGMAN_KEY_PRESS_CHAR_OFFSET
Hangman value to minus from key press to get char representation.
Definition Globals.hpp:446
static const std::array< std::string, G_HANGMAN_NUMBER_OF_COMPUTER_WORDS > G_HANGMAN_COMPUTER_WORDS
Hangman computer word list for when the computer is asked to chose a word to be guessed.
Definition Globals.hpp:598
static constexpr T ImplementStdRangesFind(const T &p_begin, const T &p_end, const U &p_value)
Implements std::ranges::find which should work for all standard template library containers.
Definition Globals.hpp:86
static const uint32_t G_HANGMAN_GET_WORD_FROM_USER_COLUMN
Hangman cursor position when getting user input on Windows.
Definition Globals.hpp:439
static const uint32_t G_HANGMAN_MAXIMUM_WORD_SIZE
Hangman word to be guessed constraints.
Definition Globals.hpp:431
static const uint32_t G_TERMINAL_ENTER_KEY
Keyboard values when getting user input on Windows.
Definition Globals.hpp:349
static const std::string G_HANGMAN_GUESSER
Hangman player choice options.
Definition Globals.hpp:588
static const std::vector< std::string > G_GAME_MAX_TWO_PLAYERS_OPTIONS
Used by multiple games or an attribute not specific to one game.
Definition Globals.hpp:386
static const uint32_t G_TERMINAL_UP_ARROW_KEY
Keyboard values when getting user input on Windows.
Definition Globals.hpp:351
static const uint32_t G_HANGMAN_MAXIMUM_ERROR_COUNT
Hangman maximum errors count to determine whether the game is over.
Definition Globals.hpp:451
static const uint32_t G_HANGMAN_USER_INPUT_ROW
Hangman cursor position when getting user input on Windows.
Definition Globals.hpp:438
static const std::string G_HANGMAN_WORD_SETTER
Hangman player choice options.
Definition Globals.hpp:589
static const std::vector< std::string > G_GAME_COMPUTER_SPEED_OPTIONS
Used by multiple games or an attribute not specific to one game.
Definition Globals.hpp:385
static const std::vector< std::string > G_HANGMAN_PLAYER_CHOICE_OPTIONS
Hangman player choice options.
Definition Globals.hpp:590
static const uint32_t G_TERMINAL_DOWN_ARROW_KEY
Keyboard values when getting user input on Windows.
Definition Globals.hpp:352
static const uint32_t G_HANGMAN_MINIMUM_WORD_SIZE
Hangman word to be guessed constraints.
Definition Globals.hpp:430
static const char G_HANGMAN_HIDDEN_LETTER
Hangman constants used to construct the hangman.
Definition Globals.hpp:467
static const uint32_t G_TERMINAL_QUIT_KEY
Keyboard values when getting user input on Windows.
Definition Globals.hpp:355
static const std::string G_GAME_UNKNOWN_OPTION
Used by multiple games or an attribute not specific to one game.
Definition Globals.hpp:382
Contains all Terminal-Games objects.
@ HANGMAN
Page supported by PageBuilder.