Terminal Games
Simple games that run in the terminal.
Loading...
Searching...
No Matches
TicTacToe.cpp
1#include <chrono>
2#include <cstdint>
3#include <string>
4#include <thread>
5#include <tuple>
6#include <vector>
7
8#include "helpers/Globals.hpp"
9#include "helpers/PageBuilder.hpp"
10#include "helpers/Terminal.hpp"
11
12#include "games/TicTacToe.hpp"
13
14namespace TerminalGames
15{
16 TicTacToe::TicTacToe(const bool& p_useAnsiEscapeCodes) :
18 m_turnCount(0),
20 m_hasWinner(false),
22 {
23 m_pageBuilder.SetProperties(Pages::TICTACTOE, p_useAnsiEscapeCodes);
24 m_randomNumberGenerator.seed(std::chrono::system_clock::now().time_since_epoch().count());
25 }
26
28 {
30 m_commandsRemaining.clear();
31 m_previousCommand = {0, 0};
32 m_turnCount = 0;
33 m_hasWinner = false;
34
35 for (uint32_t row = 0; row < Globals::G_TICTACTOE_GRID_HEIGHT; row++)
36 {
37 for (uint32_t column = 0; column < Globals::G_TICTACTOE_GRID_WIDTH; column++)
38 {
40 m_commandsRemaining.emplace_back(row, column);
41 }
42 }
43 }
44
70
72 {
73 m_gameInformation.m_ticTacToeGameInformation = {
74 .m_gameGrid = m_gameGrid,
75 .m_computerSpeedName = m_computerSpeedName,
76 .m_currentPlayer = m_currentPlayer,
77 .m_playerCount = m_playerCount,
78 .m_turnCount = m_turnCount,
79 .m_hasWinner = m_hasWinner,
80 };
81 }
82
84 {
85 // Check horizontals
86 if ((m_gameGrid[0][0] != Globals::G_TICTACTOE_EMPTY_GRID_VALUE && m_gameGrid[0][0] == m_gameGrid[0][1] && m_gameGrid[0][1] == m_gameGrid[0][2]) ||
87 (m_gameGrid[1][0] != Globals::G_TICTACTOE_EMPTY_GRID_VALUE && m_gameGrid[1][0] == m_gameGrid[1][1] && m_gameGrid[1][1] == m_gameGrid[1][2]) ||
88 (m_gameGrid[2][0] != Globals::G_TICTACTOE_EMPTY_GRID_VALUE && m_gameGrid[2][0] == m_gameGrid[2][1] && m_gameGrid[2][1] == m_gameGrid[2][2]) ||
89
90 // Check verticals
91 (m_gameGrid[0][0] != Globals::G_TICTACTOE_EMPTY_GRID_VALUE && m_gameGrid[0][0] == m_gameGrid[1][0] && m_gameGrid[1][0] == m_gameGrid[2][0]) ||
92 (m_gameGrid[0][1] != Globals::G_TICTACTOE_EMPTY_GRID_VALUE && m_gameGrid[0][1] == m_gameGrid[1][1] && m_gameGrid[1][1] == m_gameGrid[2][1]) ||
93 (m_gameGrid[0][2] != Globals::G_TICTACTOE_EMPTY_GRID_VALUE && m_gameGrid[0][2] == m_gameGrid[1][2] && m_gameGrid[1][2] == m_gameGrid[2][2]) ||
94
95 // Check diagonals
96 (m_gameGrid[0][0] != Globals::G_TICTACTOE_EMPTY_GRID_VALUE && m_gameGrid[0][0] == m_gameGrid[1][1] && m_gameGrid[1][1] == m_gameGrid[2][2]) ||
98 {
99 m_hasWinner = true;
100 return m_hasWinner;
101 }
102
104 }
105
110
115
117 {
118 while (true)
119 {
120 const std::tuple<uint32_t, uint32_t> SELECTED_COMMAND = Terminal::GetUserCommandFromGameGrid(m_previousCommand, m_pageBuilder, m_gameInformation, true);
121
122 if (ValidateCommand(SELECTED_COMMAND))
123 {
124 ExecuteGeneralCommand(SELECTED_COMMAND);
125 m_previousCommand = SELECTED_COMMAND;
126 return;
127 }
128 }
129 }
130
132 {
134
135 std::this_thread::sleep_until(std::chrono::system_clock::now() + std::chrono::seconds(m_computerSpeed));
136
137 const std::tuple<uint32_t, uint32_t> SELECTED_COMMAND = m_commandsRemaining[m_randomNumberGenerator() % m_commandsRemaining.size()];
138
139 if (ValidateCommand(SELECTED_COMMAND))
140 {
141 ExecuteGeneralCommand(SELECTED_COMMAND);
142 }
143 }
144
146 {
147 Terminal::GetUserChoiceFromGameOverMenu(m_pageBuilder.GetGameOverPage(m_gameInformation), m_pageBuilder.GetQuitOptionSelectionPage());
148 }
149
151 {
152 m_saveGameOptions = true;
153 }
154
156 {
157 m_saveGameOptions = false;
158 m_hasSavedGameOptions = false;
159 }
160
162 {
164
165 const std::vector<std::string> MENUS = m_pageBuilder.GetPlayerCountOptionSelectionGamePages(m_gameInformation);
166 const std::vector<std::string> QUIT_MENUS = m_pageBuilder.GetQuitOptionSelectionPage();
168 }
169
171 {
173
174 const std::vector<std::string> MENUS = m_pageBuilder.GetUserPlayerChoiceOptionSelectionGamePages(m_gameInformation);
175 const std::vector<std::string> QUIT_MENUS = m_pageBuilder.GetQuitOptionSelectionPage();
177 }
178
180 {
182
183 const std::vector<std::string> MENUS = m_pageBuilder.GetComputerSpeedOptionSelectionGamePages(m_gameInformation);
184 const std::vector<std::string> QUIT_MENUS = m_pageBuilder.GetQuitOptionSelectionPage();
187 }
188
189 bool TicTacToe::ValidateCommand(const std::tuple<uint32_t, uint32_t>& p_command)
190 {
191 const auto COMMAND_FIND_LOCATION = Globals::ImplementStdRangesFind(m_commandsRemaining.begin(), m_commandsRemaining.end(), p_command);
192
193 return COMMAND_FIND_LOCATION != m_commandsRemaining.end();
194 }
195
196 void TicTacToe::ExecuteGeneralCommand(const std::tuple<uint32_t, uint32_t>& p_command)
197 {
198 const auto COMMAND_FIND_LOCATION = Globals::ImplementStdRangesFind(m_commandsRemaining.begin(), m_commandsRemaining.end(), p_command);
199 const uint32_t ROW = std::get<0>(p_command);
200 const uint32_t COLUMN = std::get<1>(p_command);
201
203 {
205 }
206
207 else
208 {
210 }
211
212 m_commandsRemaining.erase(COMMAND_FIND_LOCATION);
213 m_turnCount++;
214 }
215}
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 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 std::tuple< uint32_t, uint32_t > GetUserCommandFromGameGrid(const std::tuple< uint32_t, uint32_t > &p_startingGridLocation, const PageBuilder &p_pageBuilder, const GameInformation &p_gameInformation, const bool &p_displayGetUserCommandPage)
Gets a user command based on the currently displayed game grid (wrapper function around the platform-...
Definition Terminal.cpp:114
void GetUserOptions() override
Prompt the user for their choice on various game-related options.
Definition TicTacToe.cpp:45
void ResetGame() override
Update variables to allow for the game to be reset and so the user will be asked for new options.
void GetPlayerCount()
Prompts the user to select how many players will be playing the game.
void ExecuteUserCommand() override
Prompt the user to enter their command for the current turn.
void GetComputerSpeed()
Prompts the user to select how the speed of computer decision making (this does not affect the diffic...
void ExecuteGeneralCommand(const std::tuple< uint32_t, uint32_t > &p_command)
Executes the command against the game grid.
void GetUserPlayerChoice()
Prompts the user to select which player the will be playing the game as (only supported if playing ag...
uint32_t m_turnCount
The number of turns that have occurred.
TicTacToe(const bool &p_useAnsiEscapeCodes)
Constructs a new TicTacToe object.
Definition TicTacToe.cpp:16
std::tuple< uint32_t, uint32_t > m_previousCommand
The previous grid <row, column> value that was chosen by the user. This is used to return the cursor ...
bool IsGameOver() override
Check whether the game is over.
Definition TicTacToe.cpp:83
void ExecuteComputerCommand() override
Get a random command from the computer.
void GameOver() override
Display the game over message and prompt the user whether they would like to play again or quit the g...
void ToggleCurrentPlayer() override
Change the current player to the other player.
bool IsCurrentTurnUsers() override
Check whether the current turn should be executed by the user.
GameInformation m_gameInformation
Used to package up the current state of the game so it can be used by m_pageBuilder.
std::string m_currentPlayer
The name of the player whose turn it is.
std::vector< std::tuple< uint32_t, uint32_t > > m_commandsRemaining
The grid <row, column> values that have not been chosen yet.
bool m_hasSavedGameOptions
Whether the user has selected all the game options (true) or not/partially (false)....
void SetupGame() override
Clears and sets all member variables to their game start default.
Definition TicTacToe.cpp:27
std::string m_userPlayerChoice
The choice of which player the user has selected.
void RestartGame() override
Update variables to allow for the game to be restarted with the same user options.
std::string m_computerSpeedName
The name of the user selected computer speed.
PageBuilder m_pageBuilder
Used to build pages required by the game.
void UpdateGameInformation() override
Updates GameInformation to match the current state of the game.
Definition TicTacToe.cpp:71
std::string m_playerCount
The count of the user selected number of players.
std::array< std::array< std::string, Globals::G_TICTACTOE_GRID_WIDTH >, Globals::G_TICTACTOE_GRID_HEIGHT > m_gameGrid
The Tic Tac Toe grid.
bool ValidateCommand(const std::tuple< uint32_t, uint32_t > &p_command)
Checks whether the command is valid.
uint32_t m_computerSpeed
The computer speed determined by the amount of seconds the computer must wait before executing it's c...
bool m_hasWinner
Whether the game has concluded with a winner (true) or whether it is a draw (false).
std::default_random_engine m_randomNumberGenerator
Used to randomly choose the player to start the game and to randomly decide the computer's next comma...
bool m_saveGameOptions
Whether to save the user's currently selected game options (true) and restart the game or not (false)...
static const std::string G_TICTACTOE_GRID_PLAYER_X_OCCUPIED
TicTacToe grid values.
Definition Globals.hpp:408
static const std::string G_TICTACTOE_GRID_PLAYER_O_OCCUPIED
TicTacToe grid values.
Definition Globals.hpp:409
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 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_TICTACTOE_GRID_WIDTH
TicTacToe grid attributes.
Definition Globals.hpp:394
static const std::string G_TICTACTOE_EMPTY_GRID_VALUE
TicTacToe grid values.
Definition Globals.hpp:407
static const std::vector< std::string > G_TICTACTOE_PLAYER_CHOICE_OPTIONS
TicTacToe player choice options.
Definition Globals.hpp:423
static const std::string G_TICTACTOE_PLAYER_X
TicTacToe player choice options.
Definition Globals.hpp:421
static const uint32_t G_TICTACTOE_MAXIMUM_ERROR_COUNT
TicTacToe maximum errors count to determine whether the game is over.
Definition Globals.hpp:415
static const std::string G_TICTACTOE_PLAYER_O
TicTacToe player choice options.
Definition Globals.hpp:422
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 uint32_t G_TICTACTOE_GRID_HEIGHT
TicTacToe grid attributes.
Definition Globals.hpp:395
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.
@ TICTACTOE
Page supported by PageBuilder.