added solution for minesweeper field
This commit is contained in:
parent
b5adfe9750
commit
9219a29f62
181
VL03-05-01/main.cc
Normal file
181
VL03-05-01/main.cc
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <random>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
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<std::vector<ICell*>> cells;
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
this->cells = std::vector<std::vector<ICell*>>(this->rows, std::vector<ICell*>(this->columns, new UnknownCell()));
|
||||||
|
this->placeBombs();
|
||||||
|
this->placeHints();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getRandomNumber(int min, int max) {
|
||||||
|
std::uniform_int_distribution<int> 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user