Python
C++
import random
kMine = 9
class Matrix():
def __init__(self, T):
self.elem_type = T
def resize(self, rows, cols):
self.data = [self.elem_type() for _ in range(rows * cols)]
self.rows, self.cols = rows, cols
def at(self, row, col):
return self.data[row * self.cols + col]
def rows(self):
return self.rows
def cols(self):
return self.cols
class MineField():
class Spot():
def __init__(self):
self.value = 0
self.visible = False
def _spot(self):
return self.Spot()
def __init__(self, rows, cols, num_mines):
self.matrix = Matrix(self._spot)
self.matrix.resize(rows, cols)
self.rows, self.cols = rows, cols
if num_mines > rows * cols:
print("Too many mines")
mine_list = [i < num_mines for i in range(rows * cols)]
random.shuffle(mine_list)
print(mine_list)
for index, is_mine in enumerate(mine_list):
if not is_mine:
continue
row, col = index // cols, index % cols
self.matrix.at(row, col).value = kMine
for i in range(-1, 2):
for j in range(-1, 2):
if row + i < 0 or row + i >= rows or col + j < 0 or col + j >= cols:
continue
if self.matrix.at(row + i, col + j).value == kMine:
continue
self.matrix.at(row + i, col + j).value += 1
def OnClick(self, row, col):
if row < 0 or row >= self.rows or col < 0 or col >= self.cols:
return False
spot = self.matrix.at(row, col)
if spot.visible:
return False
spot.visible = True
if spot.value == kMine:
print("Boom!!!!
")
return True
if spot.value != 0:
return False
self.OnClick(row - 1, col)
self.OnClick(row, col - 1)
self.OnClick(row + 1, col)
self.OnClick(row, col + 1)
return False
def Print(self, show_hidden=False):
for i in range(self.rows):
for j in range(self.cols):
ch = '.'
if self.matrix.at(i, j).visible or show_hidden:
ch = self.matrix.at(i, j).value
print(ch, end=' ')
print()
print()
print()
if __name__ == '__main__':
mine_field = MineField(12, 10, 7);
mine_field.Print(True);
mine_field.OnClick(5, 2);
mine_field.Print();
mine_field.OnClick(2, 6);
mine_field.Print();
mine_field.OnClick(9, 3);
mine_field.Print();
mine_field.OnClick(0, 0);
mine_field.Print();
mine_field.OnClick(3, 5);
mine_field.Print();
#include <cstdlib>
#include <vector>
#include <iostream>
#include <utility>
template<typename T>
class Matrix {
public:
void resize(int rows, int cols) {
data_.resize(rows * cols);
rows_ = rows;
cols_ = cols;
}
T& at(int row, int col) {
return data_.at(row * cols_ + col);
}
int rows() const { return rows_; }
int cols() const { return cols_; }
private:
std::vector<T> data_;
int rows_ = 0;
int cols_ = 0;
};
constexpr int kMine = 9;
using std::min;
using std::max;
class MineField {
private:
struct Spot {
int value = 0;
bool visible = false;
};
Matrix<Spot> field;
public:
MineField(int rows, int cols, int num_mines) {
field.resize(rows, cols);
const int sum = rows * cols;
if (num_mines > sum) {
std::cout << "Too many mines!" << std::endl;
num_mines = sum;
}
// Fulfill all spot preparing random shuffle.
for (int i = 0; i < sum; i++) {
field.at(i / cols, i % cols).value = i < num_mines ? kMine : 0;
}
// Random shuffle.
for (int i = 0; i < min(num_mines, sum - 1); i++) {
int j = i + (rand() % (sum - i));
std::swap(field.at(i / cols, i % cols), field.at(j / cols, j % cols));
}
// Calculate value for each spot.
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
if (field.at(row, col).value != kMine) {
continue;
}
for (int i = max(0, row - 1); i <= min(rows - 1, row + 1); i++) {
for (int j = max(0, col - 1); j <= min(cols - 1, col + 1); j++) {
if ((i != row || j != col) && field.at(i, j).value != kMine) {
field.at(i, j).value++;
}
}
}
}
}
}
bool OnClick(int row, int col) {
if (row < 0 || row >= field.rows() || col < 0 || col >= field.cols()) {
return false;
}
if (field.at(row, col).visible) { return false; }
field.at(row, col).visible = true;
if (field.at(row, col).value == kMine) {
std::cout << "BOOM!" << std::endl << std::endl;
return true;
}
if (field.at(row, col).value != 0) { return false; }
OnClick(row - 1, col);
OnClick(row + 1, col);
OnClick(row, col - 1);
OnClick(row, col + 1);
return false;
}
void Print(bool show_hidden) {
for (int i = 0; i < field.rows(); ++i) {
for (int j = 0; j < field.cols(); ++j) {
if (field.at(i, j).visible || show_hidden) {
std::cout << field.at(i, j).value << " ";
} else {
std::cout << ". ";
}
}
std::cout << std::endl;
}
std::cout << std::endl;
}
};
int main() {
srand(1);
MineField mine_field(8, 11, 7);
mine_field.Print(true);
mine_field.OnClick(5, 1);
mine_field.Print(false);
mine_field.OnClick(2, 6);
mine_field.Print(false);
mine_field.OnClick(9, 3);
mine_field.Print(false);
mine_field.OnClick(0, 0);
mine_field.Print(false);
mine_field.OnClick(3, 5);
mine_field.Print(false);
return 0;
}