diff --git a/VL03-05-01/main.cc b/VL03-05-01/main.cc new file mode 100644 index 0000000..009059d --- /dev/null +++ b/VL03-05-01/main.cc @@ -0,0 +1,181 @@ +#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; +} \ No newline at end of file