-
Notifications
You must be signed in to change notification settings - Fork 0
/
GameOfLife.hpp
139 lines (123 loc) · 2.87 KB
/
GameOfLife.hpp
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef GAME_OF_LIFE_HPP
#define GAME_OF_LIFE_HPP
template <int ROWS, int COLS>
class GameOfLife
{
bool _cells[ROWS * COLS];
byte _accumulator[ROWS * COLS];
public:
GameOfLife()
{
clear();
}
constexpr int rows() {
return ROWS;
}
constexpr int cols() {
return COLS;
}
void clear()
{
for (auto& cell : _cells)
cell = false;
}
void randomize()
{
for (auto& cell : _cells)
cell = random(100) < 30;
}
bool isAlive(int row, int col)
{
return _cells[row * COLS + col];
}
void setAlive(int row, int col, bool alive)
{
_cells[row * COLS + col] = alive;
}
void update()
{
accumulateNeighbors();
updateCells();
}
private:
void accumulateNeighbors()
{
memset(_accumulator, 0, ROWS * COLS);
for (int row = 0; row < ROWS; ++row)
{
for (int col = 0; col < COLS; ++col)
{
if (!_cells[row * COLS + col]) continue;
if (row - 1 >= 0)
{
// Add to the row below
accumulateColumnNeighbors(row - 1, col);
}
else
{
// Add to the top row
accumulateColumnNeighbors(ROWS - 1, col);
}
if (row + 1 < ROWS)
{
// Add to the row above
accumulateColumnNeighbors(row + 1, col);
}
else
{
// Add to the bottom row
accumulateColumnNeighbors(0, col);
}
// Add to the current row
if (col - 1 >= 0) {
_accumulator[row * COLS + (col - 1)]++;
} else {
_accumulator[row * COLS + (COLS - 1)]++;
}
if (col + 1 < COLS) {
_accumulator[row * COLS + (col + 1)]++;
} else {
_accumulator[row * COLS + 0]++;
}
}
}
}
void accumulateColumnNeighbors(int row, int col)
{
if (col - 1 >= 0) {
// Add to column on left
_accumulator[row * COLS + (col - 1)]++;
} else {
// Add to rightmost column
_accumulator[row * COLS + (COLS - 1)]++;
}
if (col + 1 < COLS) {
// Add to column on right
_accumulator[row * COLS + (col + 1)]++;
} else {
// Add to first column
_accumulator[row * COLS + 0]++;
}
// Add to this column
_accumulator[row * COLS + col]++;
}
void updateCells()
{
for (int row = 0; row < ROWS; ++row)
{
for (int col = 0; col < COLS; ++col)
{
int index = row * COLS + col;
if (_cells[index])
{
_cells[index] = _accumulator[index] == 2 || _accumulator[index] == 3;
}
else
{
_cells[index] = _accumulator[index] == 3;
}
}
}
}
};
#endif