This commit is contained in:
Admin
2023-04-13 14:02:08 +08:00
commit 33c813630f
57 changed files with 27736 additions and 0 deletions

View File

@@ -0,0 +1 @@
//#include "game.hpp"

View File

@@ -0,0 +1,64 @@
#ifndef COLOR_H
#define COLOR_H
#include <ostream>
namespace Color {
enum class Code {
BOLD = 1,
RESET = 0,
BG_BLUE = 44,
BG_DEFAULT = 49,
BG_GREEN = 42,
BG_RED = 41,
FG_BLACK = 30,
FG_BLUE = 34,
FG_CYAN = 36,
FG_DARK_GRAY = 90,
FG_DEFAULT = 39,
FG_GREEN = 32,
FG_LIGHT_BLUE = 94,
FG_LIGHT_CYAN = 96,
FG_LIGHT_GRAY = 37,
FG_LIGHT_GREEN = 92,
FG_LIGHT_MAGENTA = 95,
FG_LIGHT_RED = 91,
FG_LIGHT_YELLOW = 93,
FG_MAGENTA = 35,
FG_RED = 31,
FG_WHITE = 97,
FG_YELLOW = 33,
};
class Modifier {
Code code;
public:
Modifier(Code pCode) : code(pCode) {}
friend std::ostream &operator<<(std::ostream &os, const Modifier &mod) {
return os << "\033[" << static_cast<int>(mod.code) << "m";
}
};
} // namespace Color
static Color::Modifier bold_off(Color::Code::RESET);
static Color::Modifier bold_on(Color::Code::BOLD);
static Color::Modifier def(Color::Code::FG_DEFAULT);
static Color::Modifier red(Color::Code::FG_RED);
static Color::Modifier green(Color::Code::FG_GREEN);
static Color::Modifier yellow(Color::Code::FG_YELLOW);
static Color::Modifier blue(Color::Code::FG_BLUE);
static Color::Modifier magenta(Color::Code::FG_MAGENTA);
static Color::Modifier cyan(Color::Code::FG_CYAN);
static Color::Modifier lightGray(Color::Code::FG_LIGHT_GRAY);
static Color::Modifier darkGray(Color::Code::FG_DARK_GRAY);
static Color::Modifier lightRed(Color::Code::FG_LIGHT_RED);
static Color::Modifier lightGreen(Color::Code::FG_LIGHT_GREEN);
static Color::Modifier lightYellow(Color::Code::FG_LIGHT_YELLOW);
static Color::Modifier lightBlue(Color::Code::FG_LIGHT_BLUE);
static Color::Modifier lightMagenta(Color::Code::FG_LIGHT_MAGENTA);
static Color::Modifier lightCyan(Color::Code::FG_LIGHT_CYAN);
#endif

View File

@@ -0,0 +1,39 @@
#ifndef GAMEGRAPHICS_H
#define GAMEGRAPHICS_H
#include <string>
#include <tuple>
enum GameBoardDimensions {
MIN_GAME_BOARD_PLAY_SIZE = 3,
MAX_GAME_BOARD_PLAY_SIZE = 10
};
enum { COMPETITION_GAME_BOARD_PLAY_SIZE = 4 };
namespace Game {
namespace Graphics {
std::string AsciiArt2048();
std::string BoardInputPrompt();
std::string YouWinPrompt();
std::string GameOverPrompt();
std::string EndOfEndlessPrompt();
std::string InvalidInputGameBoardErrorPrompt();
std::string QuestionEndOfWinningGamePrompt();
std::string GameStateNowSavedPrompt();
std::string GameBoardNoSaveErrorPrompt();
std::string BoardSizeErrorPrompt();
std::string InputCommandListPrompt();
std::string EndlessModeCommandListPrompt();
std::string InputCommandListFooterPrompt();
using scoreboard_display_data_t =
std::tuple<bool, std::string, std::string, std::string>;
std::string GameScoreBoardBox(scoreboard_display_data_t scdd);
std::string GameScoreBoardOverlay(scoreboard_display_data_t scdd);
using end_screen_display_data_t = std::tuple<bool, bool>;
std::string GameEndScreenOverlay(end_screen_display_data_t esdd);
using input_controls_display_data_t = std::tuple<bool, bool>;
std::string GameInputControlsOverlay(input_controls_display_data_t gamestatus);
} // namespace Graphics
} // namespace Game
#endif

View File

@@ -0,0 +1,71 @@
#ifndef GAMEINPUT_H
#define GAMEINPUT_H
#include <array>
namespace Game {
namespace Input {
namespace Keypress {
namespace Code {
enum { CODE_ESC = 27, CODE_LSQUAREBRACKET = '[' };
// Hotkey bindings:
// Style: ANSI (Arrow Keys)
enum {
CODE_ANSI_TRIGGER_1 = CODE_ESC,
CODE_ANSI_TRIGGER_2 = CODE_LSQUAREBRACKET
};
enum {
CODE_ANSI_UP = 'A',
CODE_ANSI_DOWN = 'B',
CODE_ANSI_LEFT = 'D',
CODE_ANSI_RIGHT = 'C'
};
// Style: WASD
enum {
CODE_WASD_UP = 'W',
CODE_WASD_DOWN = 'S',
CODE_WASD_LEFT = 'A',
CODE_WASD_RIGHT = 'D'
};
// Style: Vim
enum {
CODE_VIM_UP = 'K',
CODE_VIM_DOWN = 'J',
CODE_VIM_LEFT = 'H',
CODE_VIM_RIGHT = 'L'
};
enum {
CODE_HOTKEY_ACTION_SAVE = 'Z',
CODE_HOTKEY_ALTERNATE_ACTION_SAVE = 'P',
CODE_HOTKEY_QUIT_ENDLESS_MODE = 'X',
CODE_HOTKEY_CHOICE_NO = 'N',
CODE_HOTKEY_CHOICE_YES = 'Y',
CODE_HOTKEY_PREGAMEMENU_BACK_TO_MAINMENU = 0
};
} // namespace Code
} // namespace Keypress
enum IntendedMoveFlag {
FLAG_MOVE_LEFT,
FLAG_MOVE_RIGHT,
FLAG_MOVE_UP,
FLAG_MOVE_DOWN,
MAX_NO_INTENDED_MOVE_FLAGS
};
using intendedmove_t = std::array<bool, MAX_NO_INTENDED_MOVE_FLAGS>;
bool check_input_ansi(char c, intendedmove_t &intendedmove);
bool check_input_vim(char c, intendedmove_t &intendedmove);
bool check_input_wasd(char c, intendedmove_t &intendedmove);
} // namespace Input
} // namespace Game
#endif

View File

@@ -0,0 +1,11 @@
#ifndef GAMEPREGAMEMENU_H
#define GAMEPREGAMEMENU_H
namespace Game {
namespace PreGameSetup {
void SetUpNewGame();
void ContinueOldGame();
} // namespace PreGameSetup
} // namespace Game
#endif

View File

@@ -0,0 +1,15 @@
#ifndef GAME_H
#define GAME_H
namespace Game {
struct GameBoard;
enum class PlayGameFlag { BrandNewGame, ContinuePreviousGame };
void playGame(PlayGameFlag cont, GameBoard gb,
unsigned long long userInput_PlaySize = 1);
void startGame();
void continueGame();
}; // namespace Game
#endif

View File

@@ -0,0 +1,16 @@
#ifndef GAMEBOARDGRAPHICS_H
#define GAMEBOARDGRAPHICS_H
#include <string>
namespace Game {
struct GameBoard;
namespace Gameboard {
namespace Graphics {
std::string GameBoardTextOutput(GameBoard gb);
}
} // namespace Gameboard
} // namespace Game
#endif

View File

@@ -0,0 +1,49 @@
#ifndef GAMEBOARD_H
#define GAMEBOARD_H
#include "tile.hpp"
#include <tuple>
#include <vector>
struct point2D_t;
namespace Game {
struct GameBoard {
using tile_data_array_t = std::vector<tile_t>;
using gameboard_data_array_t = std::tuple<size_t, tile_data_array_t>;
gameboard_data_array_t gbda;
bool win{};
bool moved{true};
ull score{};
ull largestTile{2};
long long moveCount{-1};
GameBoard() = default;
explicit GameBoard(ull playsize);
explicit GameBoard(ull playsize, tile_data_array_t prempt_board);
};
size_t getPlaySizeOfGameboardDataArray(GameBoard::gameboard_data_array_t gbda);
tile_t getTileOnGameboardDataArray(GameBoard::gameboard_data_array_t gbda,
point2D_t pt);
bool hasWonOnGameboard(GameBoard gb);
long long MoveCountOnGameBoard(GameBoard gb);
void unblockTilesOnGameboard(GameBoard &gb);
bool canMoveOnGameboard(GameBoard &gb);
bool addTileOnGameboard(GameBoard &gb);
void registerMoveByOneOnGameboard(GameBoard &gb);
void tumbleTilesUpOnGameboard(GameBoard &gb);
void tumbleTilesDownOnGameboard(GameBoard &gb);
void tumbleTilesLeftOnGameboard(GameBoard &gb);
void tumbleTilesRightOnGameboard(GameBoard &gb);
std::string printStateOfGameBoard(GameBoard gb);
} // namespace Game
#endif

View File

@@ -0,0 +1,54 @@
#ifndef GLOBAL_H
#define GLOBAL_H
#include <iosfwd>
#include <string>
using ull = unsigned long long;
void getKeypressDownInput(char &);
template<typename T>
void DrawAlways(std::ostream &os, T f) {
os << f();
}
template<typename T>
void DrawOnlyWhen(std::ostream &os, bool trigger, T f) {
if (trigger) {
DrawAlways(os, f);
}
}
template<typename T>
void DrawAsOneTimeFlag(std::ostream &os, bool &trigger, T f) {
if (trigger) {
DrawAlways(os, f);
trigger = !trigger;
}
}
template<typename suppliment_t>
struct DataSupplimentInternalType {
suppliment_t suppliment_data;
template<typename function_t>
std::string operator()(function_t f) const {
return f(suppliment_data);
}
};
template<typename suppliment_t, typename function_t>
auto DataSuppliment(suppliment_t needed_data, function_t f) {
using dsit_t = DataSupplimentInternalType<suppliment_t>;
const auto lambda_f_to_return = [=]() {
const dsit_t depinject_func = dsit_t{needed_data};
return depinject_func(f);
};
return lambda_f_to_return;
}
void pause_for_keypress();
void wait_for_any_letter_input(std::istream &is);
void clearScreen();
std::string secondsFormat(double);
#endif

View File

@@ -0,0 +1,21 @@
#ifndef LOADRESOURCE_H
#define LOADRESOURCE_H
#include <string>
#include <tuple>
namespace Game {
using load_gameboard_status_t = std::tuple<bool, struct GameBoard>;
namespace Loader {
load_gameboard_status_t load_GameBoard_data_from_file(std::string filename);
// Output: {[loadfile_ok_status], [decltype(gameboard.score)],
// [decltype(gameboard.moveCount)]}
std::tuple<bool, std::tuple<unsigned long long, long long>>
load_game_stats_from_file(std::string filename);
} // namespace Loader
} // namespace Game
#endif

View File

@@ -0,0 +1,18 @@
#ifndef MENUGRAPHICS_H
#define MENUGRAPHICS_H
#include <string>
namespace Game {
namespace Graphics {
namespace Menu {
std::string MainMenuTitlePrompt();
std::string MainMenuOptionsPrompt();
std::string InputMenuErrorInvalidInputPrompt();
std::string InputMenuPrompt();
std::string MainMenuGraphicsOverlay(bool input_error_choice_invalid);
} // namespace Menu
} // namespace Graphics
} // namespace Game
#endif

View File

@@ -0,0 +1,8 @@
#ifndef MENU_H
#define MENU_H
namespace Menu {
void startMenu();
} // namespace Menu
#endif

View File

@@ -0,0 +1,56 @@
#ifndef POINT_2D_H
#define POINT_2D_H
#include <tuple>
class point2D_t {
// Simple {x,y} datastructure = std::tuple<int, int>...
using point_datatype_t = typename std::tuple<int, int>;
point_datatype_t point_vector{};
explicit point2D_t(const point_datatype_t pt) : point_vector{pt} {}
public:
enum class PointCoord { COORD_X, COORD_Y };
point2D_t() = default;
point2D_t(const int x, const int y) : point2D_t(std::make_tuple(x, y)) {}
template<PointCoord dimension>
int get() const {
return std::get<static_cast<int>(dimension)>(point_vector);
}
template<PointCoord dimension>
void set(int value) {
std::get<static_cast<int>(dimension)>(point_vector) = value;
}
point_datatype_t get() const { return point_vector; }
void set(point_datatype_t value) { point_vector = value; }
void set(const int x, const int y) { set(std::make_tuple(x, y)); }
point2D_t &operator+=(const point2D_t &pt) {
this->point_vector = std::make_tuple(
get<PointCoord::COORD_X>() + pt.get<PointCoord::COORD_X>(),
get<PointCoord::COORD_Y>() + pt.get<PointCoord::COORD_Y>());
return *this;
}
point2D_t &operator-=(const point2D_t &pt) {
this->point_vector = std::make_tuple(
get<PointCoord::COORD_X>() - pt.get<PointCoord::COORD_X>(),
get<PointCoord::COORD_Y>() - pt.get<PointCoord::COORD_Y>());
return *this;
}
};
inline point2D_t operator+(point2D_t l, const point2D_t &r) {
l += r;
return l;
}
inline point2D_t operator-(point2D_t l, const point2D_t &r) {
l -= r;
return l;
}
#endif

View File

@@ -0,0 +1,15 @@
#ifndef SAVERESOURCE_H
#define SAVERESOURCE_H
#include <string>
#include <tuple>
namespace Game {
struct GameBoard;
namespace Saver {
void saveGamePlayState(GameBoard gb);
} // namespace Saver
} // namespace Game
#endif

View File

@@ -0,0 +1,23 @@
#ifndef SCORESGRAPHICS_H
#define SCORESGRAPHICS_H
#include <string>
#include <tuple>
#include <vector>
namespace Scoreboard {
namespace Graphics {
using scoreboard_display_data_t =
std::tuple<std::string, std::string, std::string, std::string, std::string,
std::string, std::string>;
using scoreboard_display_data_list_t = std::vector<scoreboard_display_data_t>;
std::string ScoreboardOverlay(scoreboard_display_data_list_t sbddl);
using finalscore_display_data_t =
std::tuple<std::string, std::string, std::string, std::string>;
std::string EndGameStatisticsPrompt(finalscore_display_data_t finalscore);
} // namespace Graphics
} // namespace Scoreboard
#endif

View File

@@ -0,0 +1,34 @@
#ifndef SCORES_H
#define SCORES_H
#include "global.hpp"
#include <iosfwd>
#include <string>
#include <tuple>
#include <vector>
namespace Scoreboard {
struct Score {
std::string name;
ull score;
bool win;
ull largestTile;
long long moveCount;
double duration;
};
bool operator>(const Score &a, const Score &b);
using Scoreboard_t = std::vector<Score>;
using load_score_status_t = std::tuple<bool, Scoreboard_t>;
// List of scores read until "exhausted".
// Note: returns a tuple containing a std::vector<Score> of all read scores.
load_score_status_t loadFromFileScore(std::string filename);
void saveScore(Score finalscore);
} // namespace Scoreboard
std::istream &operator>>(std::istream &is, Scoreboard::Score &s);
std::ostream &operator<<(std::ostream &os, Scoreboard::Score &s);
#endif

View File

@@ -0,0 +1,19 @@
#ifndef STATISTICSGRAPHICS_H
#define STATISTICSGRAPHICS_H
#include <string>
#include <tuple>
namespace Statistics {
namespace Graphics {
std::string AskForPlayerNamePrompt();
std::string MessageScoreSavedPrompt();
using total_stats_display_data_t =
std::tuple<bool, std::string, std::string, std::string, std::string,
std::string>;
std::string TotalStatisticsOverlay(total_stats_display_data_t tsdd);
} // namespace Graphics
} // namespace Statistics
#endif

View File

@@ -0,0 +1,34 @@
#ifndef STATISTICS_H
#define STATISTICS_H
#include "global.hpp"
#include <iosfwd>
#include <string>
#include <tuple>
namespace Scoreboard {
struct Score;
}
namespace Statistics {
struct total_game_stats_t {
ull bestScore{};
ull totalMoveCount{};
int gameCount{};
double totalDuration{};
int winCount{};
};
using load_stats_status_t = std::tuple<bool, total_game_stats_t>;
load_stats_status_t loadFromFileStatistics(std::string filename);
ull load_game_best_score();
void saveEndGameStats(Scoreboard::Score finalscore);
void CreateFinalScoreAndEndGameDataFile(std::ostream &os, std::istream &is,
Scoreboard::Score finalscore);
} // namespace Statistics
std::istream &operator>>(std::istream &is, Statistics::total_game_stats_t &s);
std::ostream &operator<<(std::ostream &os, Statistics::total_game_stats_t &s);
#endif

View File

@@ -0,0 +1,11 @@
#ifndef TILEGRAPHICS_H
#define TILEGRAPHICS_H
#include <string>
namespace Game {
struct tile_t;
std::string drawTileString(tile_t currentTile);
} // namespace Game
#endif

View File

@@ -0,0 +1,13 @@
#ifndef TILE_H
#define TILE_H
#include "global.hpp"
namespace Game {
struct tile_t {
ull value{};
bool blocked{};
};
} // namespace Game
#endif