#include "terminal-game-utils.hpp" #include #include #include #include #include #include #include #include struct termios orig_termios; class Snake { private: struct mSnakeUnit { int x; int y; std::string direction; std::string appearance; }; const std::string HEAD_ARROWS = "⇐⇓⇑⇒"; const std::string SNAKE_BODY = "═║╔╗╚╝"; bool mSnakeAteApple = false; char mSnakeDirection = 'r'; bool running = true; int mWidth, mHeight, mStartingSpeed; double mAcceleration; std::queue mSnake; std::queue mKeyQueue; std::string mRepeat(int times, std::string str) { std::string returned; for (int i = 0; i < times; i++) returned += str; return returned; } std::string mGetTurningCharacter(std::string ldur) { if (ldur.length() != 2) return ""; if (ldur == "lr") return "═"; if (ldur == "du") return "║"; if (ldur == "dr") return "╔"; if (ldur == "ld") return "╗"; if (ldur == "ur") return "╚"; if (ldur == "lu") return "╝"; return ""; } void mPrintBoardOutlines() { TGU::MoveCursor(0, 0); std::string horizontalLine = mRepeat(mWidth * 2 - 1, "═"); std::string horizontalSpaces = std::string(mWidth * 2 - 1, ' '); std::cout << "╔" << horizontalLine + "╗" << std::endl; for (int i = 0; i < mHeight; i++) { std::cout << "║" + horizontalSpaces << "║" << std::endl; } std::cout << "╚" << horizontalLine + "╝" << std::endl; } void mSetSnakeDirection() { TGU::GameKey popped = mKeyQueue.front(); if (popped == TGU::GameKey::W || popped == TGU::GameKey::UPARROW) mSnakeDirection = 'u'; if (popped == TGU::GameKey::A || popped == TGU::GameKey::LEFTARROW) mSnakeDirection = 'l'; if (popped == TGU::GameKey::S || popped == TGU::GameKey::DOWNARROW) mSnakeDirection = 'd'; if (popped == TGU::GameKey::D || popped == TGU::GameKey::RIGHTARROW) mSnakeDirection = 'r'; } void mSnakeStep() { if (!mSnakeAteApple) mSnake.pop(); mSnake.push({1, 2, mSnakeDirection, ""}) } void mGameTick() { if (mKeyQueue.size() != 0) { mSetSnakeDirection(); mSnakeStep(); } } void mInputLoop() { TGU::GameKey key; while (running) { key = TGU::GetKeyPress(); } } void mGameLoop() { while (running) { mGameTick(); } } public: struct GameSettings { int width = 14; int height = 14; int startingSpeed = 3; double acceleration = 0.3; }; Snake(const GameSettings &settings) : mWidth(settings.width), mHeight(settings.height), mStartingSpeed(settings.startingSpeed), mAcceleration(settings.acceleration) { if (mWidth < 5) mWidth = 5; if (mHeight < 5) mHeight = 5; } void StartGame() { mPrintBoardOutlines(); mSnake.push({0, 2, "lr", "═"}); mSnake.push({1, 2, "lr", "═"}); mSnake.push({2, 2, "lr", "═"}); mSnake.push({3, 2, "lr", "⇒"}); auto InputLoopResponse = std::async(std::launch::async, [this] { mInputLoop(); }); mInputLoop(); } }; int main() { TGU::EnableRawMode(); Snake hi({}); hi.StartGame(); }