generated from Coding-Cuddles/bootstrap-cpp-kata
-
Notifications
You must be signed in to change notification settings - Fork 1
/
game.h
88 lines (72 loc) · 2.4 KB
/
game.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <stdexcept>
#include <vector>
class Cell {
public:
Cell(size_t row, size_t column) : row(row), column(column) {}
virtual ~Cell() = default;
size_t get_neighbor_count(const std::vector<std::vector<size_t>>& grid) const
{
size_t rows = grid.size();
size_t columns = grid[0].size();
size_t above = 0;
size_t below = 0;
for (int i = -1; i < 2; ++i) {
size_t col = (column + i + columns) % columns;
above += grid[(row - 1 + rows) % rows][col];
below += grid[(row + 1 + rows) % rows][col];
}
size_t left = grid[row][(column - 1 + columns) % columns];
size_t right = grid[row][(column + 1 + columns) % columns];
return above + below + left + right;
}
virtual bool will_stay_alive(const std::vector<std::vector<size_t>>& grid) const = 0;
protected:
size_t row;
size_t column;
};
class Critter final : public Cell {
public:
using Cell::Cell;
bool will_stay_alive(const std::vector<std::vector<size_t>>& grid) const final
{
auto neighbors = get_neighbor_count(grid);
return 1 < neighbors && neighbors < 4;
}
};
class Space final : public Cell {
public:
using Cell::Cell;
bool will_stay_alive(const std::vector<std::vector<size_t>>& grid) const final
{
throw std::runtime_error("Space cell is always dead");
}
bool will_be_born(const std::vector<std::vector<size_t>>& grid) const
{
return get_neighbor_count(grid) == 3;
}
};
class Game {
public:
Game(std::vector<std::vector<size_t>> grid) : grid(std::move(grid)) {}
void iterate()
{
std::vector<std::vector<size_t>> new_grid;
for (size_t row_num = 0; row_num < grid.size(); ++row_num) {
std::vector<size_t> new_row;
for (size_t col_num = 0; col_num < grid[row_num].size(); ++col_num) {
size_t cell = grid[row_num][col_num];
if (cell) {
Critter cell_obj(row_num, col_num);
new_row.push_back(cell_obj.will_stay_alive(grid));
}
else {
Space cell_obj(row_num, col_num);
new_row.push_back(cell_obj.will_be_born(grid));
}
}
new_grid.push_back(new_row);
}
grid = new_grid;
}
std::vector<std::vector<size_t>> grid;
};