├── .appveyor.yml ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── data └── scores.txt ├── image └── demo.gif ├── run.sh ├── snap ├── snap.sh └── snapcraft.yaml └── src ├── block.cpp ├── block.hpp ├── color.hpp ├── drawer.cpp ├── drawer.hpp ├── game.cpp ├── game.hpp ├── main.cpp ├── util.cpp └── util.hpp /.appveyor.yml: -------------------------------------------------------------------------------- 1 | image: 2 | - Visual Studio 2015 3 | 4 | environment: 5 | MINGW_DIR: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin 6 | 7 | clone_depth: 3 8 | 9 | build: off 10 | 11 | init: 12 | - cmd: set PATH=%MINGW_DIR%;%PATH% 13 | - cmd: mklink %MINGW_DIR%\make.exe %MINGW_DIR%\mingw32-make.exe 14 | 15 | test_script: 16 | - cmake -G"MSYS Makefiles" . && make && echo "2" | stacker.exe 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | cmake-build-debug 4 | CMakeCache.txt 5 | cmake_install.cmake 6 | CMakeFiles 7 | Stack 8 | stacker* 9 | demo.yml 10 | Win/Win.VC 11 | Win/Debug 12 | Win/Win/Debug 13 | Stack.cbp 14 | build/*.o 15 | .score.txt 16 | compile_commands.json 17 | Makefile 18 | parts/ 19 | prime/ 20 | stage/ 21 | *.snap 22 | install_manifest.txt 23 | # Snapcraft global state tracking data(automatically generated) 24 | # https://forum.snapcraft.io/t/location-to-save-global-state/768 25 | /snap/.snapcraft/ 26 | 27 | # Source archive packed by `snapcraft cleanbuild` before pushing to the LXD container 28 | /*_source.tar.bz2 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | group: travis_latest 3 | 4 | git: 5 | depth: 3 6 | quiet: true 7 | 8 | os: 9 | - linux 10 | - osx 11 | 12 | compiler: 13 | - clang 14 | - gcc 15 | 16 | script: 17 | - cmake . && make -j4 18 | - echo "2" | ./stacker 19 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9.2) 2 | project(stacker) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++11 -pthread") 7 | 8 | file(GLOB_RECURSE SOURCE main.cpp src/*.cpp) 9 | 10 | add_custom_target( 11 | play 12 | COMMAND make && ./stacker 13 | ) 14 | 15 | add_executable(stacker ${SOURCE}) 16 | 17 | install(TARGETS stacker RUNTIME DESTINATION bin) 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 nploi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # stack 2 | [![Build status](https://ci.appveyor.com/api/projects/status/3d789stpq7s2s0gd/branch/master?svg=true)](https://ci.appveyor.com/project/nploi/stack) [![Build Status](https://travis-ci.com/nploi/stack.svg?branch=master)](https://travis-ci.com/nploi/stack) 3 | 4 | Terminal version of the game "stack" written in C++. 5 | 6 | ## Get it 7 | [![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/stacker) 8 | 9 | ## Demo 10 | ![Demo of usage](image/demo.gif) 11 | 12 | ## Install 13 | * Support Linux, macOs and Windows. [Download](https://github.com/nploi/stack/releases) 14 | * Or 15 | ```` 16 | git clone https://github.com/nploi/stack.git 17 | cd stack 18 | cmake . && make play 19 | ```` 20 | -------------------------------------------------------------------------------- /data/scores.txt: -------------------------------------------------------------------------------- 1 | 0 -------------------------------------------------------------------------------- /image/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nploi/stack/480f374a3c1ba6317e12589336849e213f14508e/image/demo.gif -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmake . && make play 3 | -------------------------------------------------------------------------------- /snap/snap.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd .. 3 | rm -rf CMakeCache.txt 4 | echo 'Removed CMakeCache.txt' 5 | snapcraft 6 | snapcraft login 7 | snapcraft push --release=edge stacker_*.snap -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: stacker # you probably want to 'snapcraft register ' 2 | base: core18 # the base snap is the execution environment for this snap 3 | version: '0.1' # just for humans, typically '1.2+git' or '1.3.2' 4 | summary: Stacker # 79 char long summary 5 | description: The stacker game 6 | 7 | grade: devel # must be 'stable' to release into candidate/stable channels 8 | confinement: devmode # use 'strict' once you have the right plugs and slots 9 | 10 | parts: 11 | stacker: 12 | plugin: cmake 13 | source: . 14 | build-packages: 15 | - g++ 16 | apps: 17 | stacker: 18 | command: stacker -------------------------------------------------------------------------------- /src/block.cpp: -------------------------------------------------------------------------------- 1 | #include "block.hpp" 2 | 3 | Block::Block(int size, int color) { 4 | this->size = size; 5 | this->color = color; 6 | } 7 | 8 | void Block::removeRight(int num) { 9 | this->size -= num; 10 | } 11 | 12 | void Block::removeLeft(int num) { 13 | this->size -= num; 14 | this->x += num; 15 | } 16 | 17 | void Block::addLeft(int num) { 18 | this->size += num; 19 | this->x -= num; 20 | } 21 | 22 | void Block::addRight(int num) { 23 | this->size += num; 24 | } 25 | 26 | void Block::destroy() { 27 | Util::gotoxy(x, y); 28 | cout << Color::color(Color::Code::RESET); 29 | for (int i = 0; i <= this->size; ++i) { 30 | cout << ' '; 31 | } 32 | } 33 | 34 | void Block::move(int x, int y) { 35 | this->x = x; 36 | this->y = y; 37 | } 38 | 39 | void Block::display() { 40 | Util::gotoxy(x, y); 41 | cout << Color::color(this->color); 42 | for (int i = 0; i < this->size; ++i) { 43 | cout << BLOCK; 44 | } 45 | cout << endl; 46 | } 47 | 48 | Block::Block(const Block &block) { 49 | this->x = block.x; 50 | this->y = block.y; 51 | this->color = block.color; 52 | this->size = block.size; 53 | } 54 | 55 | int Block::getX() { 56 | return this->x; 57 | } 58 | 59 | int Block::getY() { 60 | return this->y; 61 | } 62 | 63 | int Block::getSize() { 64 | return this->size; 65 | } 66 | -------------------------------------------------------------------------------- /src/block.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STACK_BLOCK_H 2 | #define STACK_BLOCK_H 3 | 4 | #include "util.hpp" 5 | #include "color.hpp" 6 | 7 | #ifdef _WIN32 8 | #define BLOCK char(219) 9 | #else 10 | #define BLOCK "█" 11 | #endif // _WIN32 12 | 13 | using namespace std; 14 | 15 | class Block { 16 | public: 17 | Block(int size, int color); 18 | Block(const Block &block); 19 | ~Block() {} 20 | void removeLeft(int num); 21 | void removeRight(int num); 22 | void addLeft(int num); 23 | void addRight(int num); 24 | void display(); 25 | void move(int x, int y); 26 | void destroy(); 27 | int getX(); 28 | int getY(); 29 | int getSize(); 30 | int getColor(); 31 | 32 | private: 33 | int x; 34 | int y; 35 | int size; 36 | int color; 37 | }; 38 | 39 | #endif //STACK_BLOCK_H 40 | -------------------------------------------------------------------------------- /src/color.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_H 2 | #define COLOR_H 3 | 4 | #include 5 | 6 | namespace Color { 7 | enum Code { 8 | RESET = 0, 9 | BOLD = 1, 10 | BG_BLUE = 44, 11 | BG_DEFAULT = 49, 12 | BG_GREEN = 42, 13 | BG_RED = 41, 14 | FG_BLACK = 30, 15 | FG_BLUE = 34, 16 | FG_CYAN = 36, 17 | FG_DARK_GRAY = 90, 18 | FG_DEFAULT = 39, 19 | FG_GREEN = 32, 20 | FG_LIGHT_BLUE = 94, 21 | FG_LIGHT_CYAN = 96, 22 | FG_LIGHT_GRAY = 37, 23 | FG_LIGHT_GREEN = 92, 24 | FG_LIGHT_MAGENTA = 95, 25 | FG_LIGHT_RED = 91, 26 | FG_LIGHT_YELLOW = 93, 27 | FG_MAGENTA = 35, 28 | FG_RED = 31, 29 | FG_WHITE = 97, 30 | FG_YELLOW = 33, 31 | }; 32 | 33 | class color { 34 | int code; 35 | public: 36 | color(double pCode) : code(pCode) {} 37 | friend std::ostream &operator<<(std::ostream &os, const color &mod) { 38 | return os << "\033[" << mod.code << "m"; 39 | } 40 | }; 41 | } 42 | 43 | static int colors[] = {31, 91, 32, 92, 33, 93, 34, 94, 35, 95, 36, 96, 37, 97, 0}; 44 | static Color::color bold(Color::Code::BOLD); 45 | static Color::color fg_default(Color::Code::FG_DEFAULT); 46 | static Color::color reset(Color::Code::RESET); 47 | 48 | #endif -------------------------------------------------------------------------------- /src/drawer.cpp: -------------------------------------------------------------------------------- 1 | #include "drawer.hpp" 2 | 3 | void Drawer::menu(int x, int y) { 4 | std::cout << bold << fg_default; 5 | Util::gotoxy(x, y++); 6 | std::cout << "+------------+"; 7 | Util::gotoxy(x, y++); 8 | std::cout << "|1. New game |"; 9 | Util::gotoxy(x, y++); 10 | std::cout << "|2. Exit |"; 11 | Util::gotoxy(x, y++); 12 | std::cout << "+------------+"; 13 | Util::gotoxy(x, y++); 14 | std::cout << ">> "; 15 | } 16 | 17 | void Drawer::scores(int x, int y, long score, long bestScore) { 18 | std::cout << bold; 19 | #ifdef _WIN32 20 | Util::gotoxy(x, y++); 21 | std::cout << char(201) << std::string(12, char(205)) << char(187); 22 | Util::gotoxy(x, y++); 23 | std::cout << char(186) << "SCORE: " << char(186); 24 | Util::gotoxy(x, y++); 25 | std::cout << char(186) << "BEST: " << char(186); 26 | Util::gotoxy(x, y++); 27 | std::cout << char(200) << std::string(12, char(205)) << char(188); 28 | #else 29 | Util::gotoxy(x, y++); 30 | std::cout << "╔════════════╗\n"; 31 | Util::gotoxy(x, y++); 32 | std::cout << "║SCORE: ║\n"; 33 | Util::gotoxy(x, y++); 34 | std::cout << "║BEST: ║\n"; 35 | Util::gotoxy(x, y++); 36 | std::cout << "╚════════════╝\n"; 37 | #endif // _WIN32 38 | 39 | Util::gotoxy(x + 7, y - 3); 40 | std::cout << fg_default; 41 | std::cout << score << std::endl; 42 | Util::gotoxy(x + 7, y - 2); 43 | std::cout << bestScore << std::endl; 44 | std::cout << reset; 45 | } 46 | 47 | void Drawer::help(int x, int y) { 48 | std::cout << bold; 49 | Util::gotoxy(x - 1, y++); 50 | std::cout << "「SPACE」 play"; 51 | Util::gotoxy(x - 1, y++); 52 | std::cout << "「ESC」 menu"; 53 | } 54 | -------------------------------------------------------------------------------- /src/drawer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STACK_DRAWER_H 2 | #define STACK_DRAWER_H 3 | 4 | #include "util.hpp" 5 | #include "color.hpp" 6 | 7 | class Drawer { 8 | public: 9 | static void menu(int x, int y); 10 | static void scores(int x, int y, long score, long bestScore); 11 | static void help(int x, int y); 12 | }; 13 | 14 | 15 | #endif //STACK_DRAWER_H 16 | -------------------------------------------------------------------------------- /src/game.cpp: -------------------------------------------------------------------------------- 1 | #include "game.hpp" 2 | 3 | void Game::menu() { 4 | 5 | bestScore = getBestScore(); 6 | printBlocks((score <= MID ? MID : 5)); 7 | Drawer::menu(51, 8); 8 | char select; 9 | cin >> select; 10 | switch (select) { 11 | case '1': 12 | Game::init(); 13 | Game::start(); 14 | break; 15 | case '2': 16 | Game::save(); 17 | break; 18 | default: 19 | Game::menu(); 20 | } 21 | } 22 | 23 | void Game::save() { 24 | std::ofstream outputFile; 25 | outputFile.open(FILE_NAME, ios::out); 26 | if(outputFile.fail()) { 27 | cout << "Open file failed."; 28 | exit(1); 29 | } 30 | outputFile << bestScore; 31 | outputFile.close(); 32 | } 33 | 34 | bool Game::isContinue() { 35 | return !stop && !returnMenu; 36 | } 37 | 38 | int Game::getBestScore() { 39 | int score; 40 | std::ifstream inputFile; 41 | inputFile.open(FILE_NAME, ios::in); 42 | if (inputFile.fail()) { 43 | cout << "Created new file."; 44 | std::ofstream create(FILE_NAME); 45 | score = 0; 46 | create.close(); 47 | } else { 48 | inputFile >> score; 49 | } 50 | inputFile.close(); 51 | return score; 52 | } 53 | 54 | void Game::init() { 55 | score = 0; 56 | indexColor = Util::random(0, 14); 57 | Block defaultBlock(SIZE_BLOCK, colors[indexColor]); 58 | defaultBlock.move(MID, MID); 59 | arrBlock.clear(); 60 | insertBlock(defaultBlock); 61 | stop = false; 62 | speed = 40; 63 | gameOver = false; 64 | returnMenu = false; 65 | counter = 0; 66 | printBlocks(MID); 67 | } 68 | 69 | void Game::printBlocks(int top) { 70 | Util::clear(); 71 | for (int i = arrBlock.size() - 1; i >= 0; --i) { 72 | arrBlock[i].move(arrBlock[i].getX(), ++top); 73 | arrBlock[i].display(); 74 | if(!gameOver && top > MID) { 75 | break; 76 | } 77 | } 78 | 79 | Util::gotoxy(0, top + 1); 80 | for (int i = 0; i < SIZE_OF_TABLE; i++) { 81 | cout << '#'; 82 | } 83 | if(!gameOver && started) { 84 | Drawer::help(51, 8); 85 | } 86 | Drawer::scores(51, 4, score, bestScore); 87 | } 88 | 89 | void Game::getInput() { 90 | 91 | do { 92 | char c; 93 | Util::getchar(c); 94 | switch (c) { 95 | case SPACE: 96 | stop = true; 97 | break; 98 | case ESC: 99 | returnMenu = true; 100 | return; 101 | } 102 | } while (!gameOver); 103 | } 104 | 105 | void Game::logic() { 106 | int top = MID, topTemp = MID; 107 | int size = SIZE_BLOCK; 108 | int color = indexColor; 109 | color++; 110 | while (true) { 111 | bool odd = arrBlock.size() % 2 == 0; 112 | Block block(size, colors[color]); 113 | 114 | while (odd && isContinue()) { 115 | goRight(block, top); 116 | goLeft(block, top); 117 | } 118 | while (!odd && isContinue()) { 119 | goLeft(block, top); 120 | goRight(block, top); 121 | } 122 | 123 | if(returnMenu) { 124 | menu(); 125 | return; 126 | } 127 | 128 | if(stop) { 129 | block.destroy(); 130 | gameOver = insertBlock(block); 131 | if(gameOver) { 132 | arrBlock.push_back(block); 133 | save(); 134 | menu(); 135 | return; 136 | } 137 | score++; 138 | if(score > bestScore) { 139 | bestScore = score; 140 | } 141 | 142 | if(top == 7) { 143 | topTemp--; 144 | } else { 145 | top--; 146 | topTemp = top; 147 | } 148 | printBlocks(topTemp++); 149 | color--; 150 | if(color < 0) { 151 | color = 14; 152 | } 153 | 154 | stop = false; 155 | size = arrBlock[arrBlock.size() - 1].getSize(); 156 | } 157 | } 158 | } 159 | 160 | void Game::start() { 161 | Drawer::help(51, 8); 162 | started = true; 163 | thread thread1(&logic); 164 | thread thread2(&getInput); 165 | thread1.join(); 166 | thread2.join(); 167 | } 168 | 169 | bool Game::removeExcess(Block &block) { 170 | int size = arrBlock.size(); 171 | 172 | if(size == 0) { 173 | return false; 174 | } 175 | 176 | int start1 = block.getX(); 177 | int end1 = start1 + block.getSize(); 178 | int start2 = arrBlock[size - 1].getX(); 179 | int end2 = start2 + arrBlock[size - 1].getSize(); 180 | 181 | if (end1 <= start2) { 182 | return true; 183 | } 184 | 185 | if (start1 >= end2) { 186 | return true; 187 | } 188 | 189 | int num = start2 - start1; 190 | if(num > 0) { 191 | block.removeLeft(num); 192 | } 193 | 194 | num = end1 - end2; 195 | if(num > 0) { 196 | block.removeRight(num); 197 | } 198 | if(block.getSize() < SIZE_BLOCK && block.getSize() == arrBlock[size - 1].getSize()) { 199 | counter++; 200 | if(counter >= 4) { 201 | int numLeft = 1, numRight = 1; 202 | if(SIZE_BLOCK - block.getSize() == 1) { 203 | if(score%2==0) { 204 | numLeft = 0; 205 | } else { 206 | numRight = 0; 207 | } 208 | } 209 | block.addLeft(numLeft); 210 | block.addRight(numRight); 211 | } 212 | } else { 213 | counter = 0; 214 | } 215 | return false; 216 | } 217 | 218 | bool Game::insertBlock(Block &block) { 219 | bool result = removeExcess(block); 220 | if(!result) { 221 | arrBlock.push_back(block); 222 | } 223 | return result; 224 | } 225 | 226 | void Game::goRight(Block &block, int top) { 227 | // Move block to right 228 | for (int i = 0; i + block.getSize() <= SIZE_OF_TABLE && isContinue(); ++i) { 229 | Util::sleep(speed); 230 | block.move(i, top); 231 | block.display(); 232 | #ifdef _WIN32 233 | Util::remove(i - 1, top); 234 | #else 235 | Util::remove(i, top); 236 | #endif // _WIN32 237 | 238 | } 239 | } 240 | 241 | void Game::goLeft(Block &block, int top) { 242 | // Move block to left 243 | for (int i = SIZE_OF_TABLE - block.getSize(); i >= 0 && isContinue(); --i) { 244 | Util::sleep(speed); 245 | block.move(i, top); 246 | block.display(); 247 | #ifdef _WIN32 248 | Util::remove(i + block.getSize(), top); 249 | #else 250 | Util::remove(i + block.getSize() - 1, top); 251 | #endif // _WIN32 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /src/game.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STACK_GAME_H 2 | #define STACK_GAME_H 3 | 4 | #include "block.hpp" 5 | #include "drawer.hpp" 6 | 7 | using namespace std; 8 | 9 | #define SIZE_OF_TABLE 50 10 | #define SIZE_BLOCK 20 11 | #define FILE_NAME ".score.txt" 12 | #define MID 15 13 | #define SPACE 32 14 | #define ESC 27 15 | 16 | static int speed; 17 | static bool stop; 18 | static bool started; 19 | static vector arrBlock; 20 | static bool gameOver; 21 | static int indexColor; 22 | static bool returnMenu; 23 | static long bestScore; 24 | static long score; 25 | static long counter; 26 | 27 | class Game { 28 | public: 29 | static void menu(); 30 | static void save(); 31 | static int getBestScore(); 32 | static bool isContinue(); 33 | static void getInput(); 34 | static void init(); 35 | static void printBlocks(int top); 36 | static void start(); 37 | static void logic(); 38 | static void goLeft(Block &block, int top); 39 | static void goRight(Block &block, int top); 40 | static bool removeExcess(Block &block); 41 | static bool insertBlock(Block &block); 42 | }; 43 | 44 | #endif //STACK_GAME_H 45 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "game.hpp" 4 | #include 5 | 6 | int main() { 7 | try { 8 | Game::init(); 9 | Game::menu(); 10 | } catch(...) { 11 | exit(1); 12 | } 13 | return 0; 14 | } -------------------------------------------------------------------------------- /src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.hpp" 2 | 3 | #ifdef _WIN32 4 | void Util::gotoxy(int x, int y) { 5 | static HANDLE handle = NULL; 6 | if (!handle) { 7 | handle = GetStdHandle(STD_OUTPUT_HANDLE); 8 | } 9 | COORD coord = { x, y }; 10 | SetConsoleCursorPosition(handle, coord); 11 | } 12 | #else 13 | char getch() { 14 | char buf = 0; 15 | struct termios old = {0}; 16 | if (tcgetattr(0, &old) < 0) 17 | perror("tcsetattr()"); 18 | old.c_lflag &= ~ICANON; 19 | old.c_lflag &= ~ECHO; 20 | old.c_cc[VMIN] = 1; 21 | old.c_cc[VTIME] = 0; 22 | if (tcsetattr(0, TCSANOW, &old) < 0) 23 | perror("tcsetattr ICANON"); 24 | if (read(0, &buf, 1) < 0) 25 | perror("read()"); 26 | old.c_lflag |= ICANON; 27 | old.c_lflag |= ECHO; 28 | if (tcsetattr(0, TCSADRAIN, &old) < 0) 29 | perror("tcsetattr ~ICANON"); 30 | return (buf); 31 | } 32 | void Util::gotoxy(int x, int y) { 33 | printf("%c[%d;%df",0x1B,y,x); 34 | } 35 | #endif 36 | 37 | 38 | void Util::getchar(char &c) { 39 | #ifdef _WIN32 40 | c = _getch(); 41 | #else 42 | c = getch(); 43 | #endif 44 | } 45 | 46 | int Util::random(int a, int b) { 47 | /* initialize random seed: */ 48 | std::random_device rd; // Will be used to obtain a seed for the random number engine 49 | std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() 50 | // Use dis to transform the random unsigned int generated by gen into an int in [a, b] 51 | std::uniform_int_distribution<> dis(a, b); 52 | return dis(gen); 53 | } 54 | 55 | void Util::sleep(int miliseconds) { 56 | std::this_thread::sleep_for(std::chrono::milliseconds(miliseconds)); 57 | } 58 | 59 | void Util::clear() { 60 | #ifdef _WIN32 61 | system("cls"); 62 | #else 63 | system("clear"); 64 | #endif // _WIN32 65 | } 66 | 67 | void Util::remove(int x, int y) { 68 | gotoxy(x, y); 69 | std::cout << " "; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/util.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STACK_UTIL_H 2 | #define STACK_UTIL_H 3 | 4 | #include 5 | #include /* time */ 6 | #include /* srand, rand */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | #ifdef _WIN32 18 | #include 19 | #include 20 | #else 21 | #include 22 | #include 23 | #include 24 | #endif 25 | 26 | 27 | namespace Util { 28 | void gotoxy(int x, int y); 29 | void getchar(char &c); 30 | int random(int a, int b); 31 | void sleep(int miliseconds); 32 | void clear(); 33 | void remove(int x, int y); 34 | }; 35 | 36 | #endif //STACK_UTIL_H 37 | --------------------------------------------------------------------------------