#include #include #include #include static std::random_device rd; static std::mt19937 rng{rd()}; class ICell { public: virtual void print(bool hide) = 0; virtual char type() = 0; }; class BombCell : public ICell { public: virtual void print(bool hide) { if (hide) { std::cout << "X"; } else { std::cout << "B"; } } virtual char type() { return 'b'; } }; class UnknownCell : public ICell { public: virtual void print(bool hide) { std::cout << "X"; } virtual char type() { return 'u'; } }; class HintCell : public ICell { private: int bombs = 0; public: HintCell(int bombs) { this->bombs = bombs; } virtual void print(bool hide) { std::cout << this->bombs; } virtual char type() { return 'h'; } }; class Minesweeper { private: int rows; int columns; int bombs; std::vector> cells; void init() { this->cells = std::vector>(this->rows, std::vector(this->columns, new UnknownCell())); this->placeBombs(); this->placeHints(); } int getRandomNumber(int min, int max) { std::uniform_int_distribution uid(min, max); return uid(rng); } bool isColumnIndex(int index) { return (index < 0 || index >= this->cells[0].size()) ? false : true; } bool isRowIndex(int index) { return (index < 0 || index >= this->cells.size()) ? false : true; } int getNearBombs(int row, int column) { int bombs = 0; for (int offset_row : {-1, 0, 1}) { for (int offset_column : {-1, 0, 1}) { if (this->isRowIndex(row + offset_row) && this->isColumnIndex(column + offset_column)){ if (this->cells[row + offset_row][column + offset_column]->type() == 'b') { bombs++; } } } } return bombs; } public: Minesweeper() { this->rows = 16; this->columns = 16; this->bombs = 99; this->init(); } Minesweeper(int rows, int columns, int bombs) { this->rows = rows; this->columns = columns; this->bombs = bombs; this->init(); } ~Minesweeper() { for (int row = 0; row < this->rows; row++) { for (int column = 0; column < this->columns; column++) { delete this->cells[row][column]; } } } void placeBombs() { int placed_bombs = 0; while (placed_bombs != this->bombs) { int column = this->getRandomNumber(0, this->columns - 1); int row = this->getRandomNumber(0, this->rows - 1); if (this->cells[row][column]->type() != 'b') { this->cells[row][column] = new BombCell(); placed_bombs++; } } } void placeHints() { for (int row = 0; row < this->rows; row++) { for (int column = 0; column < this->columns; column++) { if (this->cells[row][column]->type() == 'u') { int near_bombs = this->getNearBombs(row, column); if (near_bombs > 0) { this->cells[row][column] = new HintCell(near_bombs); } } } } } void print(bool hide) { for (int row = 0; row < this->cells.size(); row++) { for (int column = 0; column < this->cells[row].size(); column++) { cells[row][column]->print(hide); } std::cout << std::endl; } } }; int main() { std::cout << "Wie viele Zeilen soll das Spielfeld haben? "; int rows; std::cin >> rows; std::cout << "Wie viele Spalten soll das Spielfeld haben? "; int columns; std::cin >> columns; std::cout << "Wie viele Bomben sollen platziert werden? "; int bombs; std::cin >> bombs; std::cout << "Sollen Bomben sichtbar sein? "; char decision; std::cin >> decision; Minesweeper* minesweeper = new Minesweeper(rows, columns, bombs); minesweeper->print((decision == 'y' || decision == 'Y') ? false : true); return 0; }