8#include <unordered_map>
12#include "helpers/GameInformation.hpp"
13#include "helpers/Globals.hpp"
14#include "helpers/PageBuilder.hpp"
15#include "helpers/Terminal.hpp"
17#include "games/Battleships.hpp"
140 std::this_thread::sleep_until(std::chrono::system_clock::now() + std::chrono::seconds(
m_computerSpeed));
174 const std::vector<std::string> QUIT_MENUS =
m_pageBuilder.GetQuitOptionSelectionPage();
183 const std::vector<std::string> QUIT_MENUS =
m_pageBuilder.GetQuitOptionSelectionPage();
195 uint32_t startingRow = 0;
196 uint32_t startingColumn = 0;
197 uint32_t lastShipStartingRow = 0;
198 uint32_t lastShipStartingColumn = 0;
199 bool shipIsHorizontal =
false;
200 bool shipIsVertical =
false;
205 std::vector<std::tuple<uint32_t, uint32_t>> currentShipPositions;
211 if (!currentShipPositions.empty())
213 startingRow = std::get<0>(currentShipPositions.back());
214 startingColumn = std::get<1>(currentShipPositions.back());
226 startingRow = lastShipStartingRow;
227 startingColumn = lastShipStartingColumn;
228 shipIsHorizontal =
false;
229 shipIsVertical =
false;
242 currentShipPositions.push_back(SELECTED_SHIP_GRID_LOCATION);
255 if (currentShipSize != 0)
259 currentShipPositions.pop_back();
264 currentShipSize -= 2;
272 lastShipStartingRow = std::get<0>(currentShipPositions.back());
273 lastShipStartingColumn = std::get<1>(currentShipPositions.back());
278 const std::vector<std::tuple<uint32_t, uint32_t>>& p_currentShipPositions,
279 const std::tuple<uint32_t, uint32_t>& p_selectedShipGridLocation,
280 bool& p_shipIsHorizontal,
281 bool& p_shipIsVertical)
286 const uint32_t SELECTED_SHIP_GRID_ROW = std::get<0>(p_selectedShipGridLocation);
287 const uint32_t SELECTED_SHIP_GRID_COLUMN = std::get<1>(p_selectedShipGridLocation);
295 if (p_currentShipPositions.empty())
302 const uint32_t PREVIOUS_SELECTED_SHIP_GRID_ROW = std::get<0>(p_currentShipPositions.back());
303 const uint32_t PREVIOUS_SELECTED_SHIP_GRID_COLUMN = std::get<1>(p_currentShipPositions.back());
305 const bool ROWS_ARE_THE_SAME = PREVIOUS_SELECTED_SHIP_GRID_ROW == SELECTED_SHIP_GRID_ROW;
306 const bool COLUMNS_ARE_THE_SAME = PREVIOUS_SELECTED_SHIP_GRID_COLUMN == SELECTED_SHIP_GRID_COLUMN;
309 if (!ROWS_ARE_THE_SAME && !COLUMNS_ARE_THE_SAME)
314 const int32_t ROW_DIFFERENCE_TO_PREVIOUS_SELECTION = std::abs(
static_cast<int32_t
>(SELECTED_SHIP_GRID_ROW) -
static_cast<int32_t
>(PREVIOUS_SELECTED_SHIP_GRID_ROW));
315 const int32_t COLUMN_DIFFERENCE_TO_PREVIOUS_SELECTION = std::abs(
static_cast<int32_t
>(SELECTED_SHIP_GRID_COLUMN) -
static_cast<int32_t
>(PREVIOUS_SELECTED_SHIP_GRID_COLUMN));
318 if ((ROW_DIFFERENCE_TO_PREVIOUS_SELECTION > 1) || (COLUMN_DIFFERENCE_TO_PREVIOUS_SELECTION > 1))
325 if (p_currentShipPositions.size() == 1)
327 p_shipIsHorizontal = ROWS_ARE_THE_SAME;
328 p_shipIsVertical = COLUMNS_ARE_THE_SAME;
333 if (p_shipIsHorizontal && !ROWS_ARE_THE_SAME)
339 if (p_shipIsVertical && !COLUMNS_ARE_THE_SAME)
352 std::vector<std::tuple<uint32_t, uint32_t>> shipPositions;
353 uint32_t startingRow = 0;
354 uint32_t startingColumn = 0;
355 bool locationIsAlreadyOccupied =
false;
359 shipPositions.clear();
360 locationIsAlreadyOccupied =
false;
378 shipPositions.emplace_back(startingRow, startingColumn + columnIncrement);
383 locationIsAlreadyOccupied =
true;
404 shipPositions.emplace_back(startingRow + rowIncrement, startingColumn);
409 locationIsAlreadyOccupied =
true;
415 if (!locationIsAlreadyOccupied)
422 for (std::tuple<uint32_t, uint32_t> currentShipPosition : shipPositions)
431 for (
const std::array<std::string, Globals::G_BATTLESHIPS_BOARD_WIDTH>& currentRow : p_board)
433 for (
const std::string& currentBoardValue : currentRow)
445 bool Battleships::ValidateCommand(
const std::vector<std::tuple<uint32_t, uint32_t>>& p_commandsRemaining,
const std::tuple<uint32_t, uint32_t>& p_command)
449 return COMMAND_FIND_LOCATION != p_commandsRemaining.end();
454 std::unordered_map<std::string, uint32_t>& p_opponentShipsRemaining,
455 std::vector<std::tuple<uint32_t, uint32_t>>& p_commandsRemaining,
456 const std::tuple<uint32_t, uint32_t>& p_command)
459 const uint32_t ROW = std::get<0>(p_command);
460 const uint32_t COLUMN = std::get<1>(p_command);
465 p_opponentShipsRemaining.at(p_opponentBoard.at(ROW).at(COLUMN))--;
474 p_commandsRemaining.erase(COMMAND_FIND_LOCATION);
void ResetGame() override
Update variables to allow for the game to be reset and so the user will be asked for new options.
void ExecuteComputerCommand() override
Get a random command from the computer.
uint32_t m_turnCount
The number of turns that have occurred.
std::unordered_map< std::string, uint32_t > m_shipsRemainingPlayerOne
The respective player's health of each their ships.
bool IsCurrentTurnUsers() override
Check whether the current turn should be executed by the user.
std::vector< std::tuple< uint32_t, uint32_t > > m_commandsRemainingPlayerOne
The respective player's board <row, column> values they have not chosen yet.
GameInformation m_gameInformation
Used to package up the current state of the game so it can be used by m_pageBuilder.
std::string m_playerCount
The count of the user selected number of players.
std::tuple< uint32_t, uint32_t > m_previousCommand
The previous board <row, column> value that was chosen by the user. This is used to return the cursor...
Battleships(const bool &p_useAnsiEscapeCodes)
Constructs a new Battleships object.
void UpdateGameInformation() override
Updates GameInformation to match the current state of the game.
void GameOver() override
Display the game over message and prompt the user whether they would like to play again or quit the g...
PageBuilder m_pageBuilder
Used to build pages required by the game.
void ExecuteUserCommand() override
Prompt the user to enter their command for the current turn.
void ExecuteGeneralCommand(std::array< std::array< std::string, Globals::G_BATTLESHIPS_BOARD_WIDTH >, Globals::G_BATTLESHIPS_BOARD_HEIGHT > &p_opponentBoard, std::unordered_map< std::string, uint32_t > &p_opponentShipsRemaining, std::vector< std::tuple< uint32_t, uint32_t > > &p_commandsRemaining, const std::tuple< uint32_t, uint32_t > &p_command)
Executes the command on the opponent's board and updates their own board and commands remaining.
void RestartGame() override
Update variables to allow for the game to be restarted with the same user options.
void GetPlayerCount()
Prompts the user to select how many players will be playing the game.
bool m_isGameOver
Whether the game is over (true) or not (false).
std::unordered_map< std::string, uint32_t > m_shipsRemainingPlayerTwo
The respective player's health of each their ships.
std::array< std::array< std::string, Globals::G_BATTLESHIPS_BOARD_WIDTH >, Globals::G_BATTLESHIPS_BOARD_HEIGHT > m_boardPlayerTwo
The current state of the respective player's board.
void GetUserShipPositions()
Prompt the user to place all ships on the board.
std::array< std::array< std::string, Globals::G_BATTLESHIPS_BOARD_WIDTH >, Globals::G_BATTLESHIPS_BOARD_HEIGHT > m_boardPlayerOne
The current state of the respective player's board.
static bool ValidateCommand(const std::vector< std::tuple< uint32_t, uint32_t > > &p_commandsRemaining, const std::tuple< uint32_t, uint32_t > &p_command)
Checks whether the command is valid.
void GetComputerSpeed()
Prompts the user to select how the speed of the computer decision making (this does not affect the di...
std::vector< std::tuple< uint32_t, uint32_t > > m_commandsRemainingPlayerTwo
The respective player's board <row, column> values they have not chosen yet.
void SetupGame() override
Clears and sets all member variables to their game start default.
std::string m_currentPlayer
The name of the player whose turn it is.
void GetRandomShipPositions(std::array< std::array< std::string, Globals::G_BATTLESHIPS_BOARD_WIDTH >, Globals::G_BATTLESHIPS_BOARD_HEIGHT > &p_board)
Randomly place all ships on the board and is used to place the computer's ships.
bool IsGameOver() override
Check whether the game is over.
static bool IsShipPresent(std::array< std::array< std::string, Globals::G_BATTLESHIPS_BOARD_WIDTH >, Globals::G_BATTLESHIPS_BOARD_HEIGHT > &p_board)
Checks whether at least a single ship is present on a game board.
std::string m_computerSpeedName
The name of the user selected computer speed.
void ToggleCurrentPlayer() override
Change the current player to the other player.
uint32_t m_computerSpeed
The computer speed determined by the amount of seconds the computer must wait before executing it's c...
bool m_saveGameOptions
Whether to save the user's currently selected game options (true) and restart the game or not (false)...
bool ValidateUserShipPosition(const std::vector< std::tuple< uint32_t, uint32_t > > &p_currentShipPositions, const std::tuple< uint32_t, uint32_t > &p_selectedShipGridLocation, bool &p_shipIsHorizontal, bool &p_shipIsVertical)
Validates whether (true) or not (false) p_selectedShipGridLocation is a valid grid location to place ...
void GetUserOptions() override
Prompt the user for their choice on various game-related options.
bool m_hasSavedGameOptions
Whether the user has selected all the game options (true) or not/partially (false)....
std::default_random_engine m_randomNumberGenerator
Used to randomly select ships positions for the computer and randomly select board <row,...
Used when the backspace key is pressed.
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...
static void PrintOutput(const std::string &p_output)
Clears and then prints to the terminal.
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.
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-...
static const uint32_t G_BATTLESHIPS_SHIP_COUNT
Battleships number of ships for each board/player.
static const std::array< std::string, G_BATTLESHIPS_SHIP_COUNT > G_BATTLESHIPS_SHIP_PLACED_NAMES
Battleships list of ship names when placed on a board.
static const uint32_t G_BATTLESHIPS_SUBMARINE_SIZE
Battleships ship-related constants used in later arrays.
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.
static const std::string G_BATTLESHIPS_SUCCESSFUL_ATTACK
Battleships board values.
static const std::string G_BATTLESHIPS_MISSED_ATTACK
Battleships board values.
static const uint32_t G_BATTLESHIPS_BOARD_WIDTH
Battleships board attributes.
static const std::string G_BATTLESHIPS_DESTROYER_PLACED_NAME
Battleships ship-related constants used in later arrays.
static const std::string G_BATTLESHIPS_BATTLESHIP_PLACED_NAME
Battleships ship-related constants used in later arrays.
static const std::array< std::string, G_GAME_TWO_OPTIONS > G_BATTLESHIPS_PLAYER_CHOICE_OPTIONS
Battleships player choice options.
static const std::string G_BATTLESHIPS_PLAYER_ONE
Battleships player choice options.
static const uint32_t G_BATTLESHIPS_PATROL_BOAT_SIZE
Battleships ship-related constants used in later arrays.
static const uint32_t G_BATTLESHIPS_GRID_ELEMENT_WIDTH
Battleships board attributes.
static const uint32_t G_BATTLESHIPS_BATTLESHIP_SIZE
Battleships ship-related constants used in later arrays.
static const std::string G_BATTLESHIPS_PLAYER_TWO
Battleships player choice options.
static const uint32_t G_BATTLESHIPS_DESTROYER_SIZE
Battleships ship-related constants used in later arrays.
static const uint32_t G_BATTLESHIPS_CARRIER_SIZE
Battleships ship-related constants used in later arrays.
static const std::string G_BATTLESHIPS_EMPTY_GRID_VALUE
Battleships board values.
static const std::string G_BATTLESHIPS_PATROL_BOAT_PLACED_NAME
Battleships ship-related constants used in later arrays.
static const std::vector< std::string > G_GAME_COMPUTER_SPEED_OPTIONS
Used by multiple games or an attribute not specific to one game.
static const std::string G_BATTLESHIPS_SUBMARINE_PLACED_NAME
Battleships ship-related constants used in later arrays.
static const std::vector< std::string > G_GAME_MAX_ONE_PLAYER_OPTIONS
Used by multiple games or an attribute not specific to one game.
static const std::array< std::string, G_BATTLESHIPS_SHIP_COUNT > G_BATTLESHIPS_SHIP_INSTRUCTIONS
Battleships list of instructions use when asking the user for the grid locations for their ships.
static const std::array< uint32_t, G_BATTLESHIPS_SHIP_COUNT > G_BATTLESHIPS_SHIP_SIZES
Battleships list of ship sizes.
static const uint32_t G_BATTLESHIPS_BOARD_HEIGHT
Battleships board attributes.
static const std::string G_BATTLESHIPS_CARRIER_PLACED_NAME
Battleships ship-related constants used in later arrays.
static const std::string G_GAME_UNKNOWN_OPTION
Used by multiple games or an attribute not specific to one game.
Contains all Terminal-Games objects.
@ BATTLESHIPS
Page supported by PageBuilder.