This repository has been archived by the owner on Aug 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgame_state_updater.cpp
83 lines (68 loc) · 3.58 KB
/
game_state_updater.cpp
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
#include "game_state_updater.h"
#include <algorithm>
bool LifeGameStateUpdater::cellExist(int rowIndex, int columnIndex, int rowCount, int columnCount) const
{
bool rowIndexValid = rowIndex >= 0 && rowIndex < rowCount;
bool columnIndexValid = columnIndex >= 0 && columnIndex < columnCount;
return rowIndexValid && columnIndexValid;
}
int LifeGameStateUpdater::aliveNeighborsCount(const BinaryField& playingField, int targetRowIndex, int targetColumnIndex) const
{
const auto rowCount = playingField.size();
const auto columnCount = playingField.at(0).size();
auto leftBound = targetColumnIndex - 1;
auto rightBound = targetColumnIndex + 1;
const auto topBound = targetRowIndex - 1;
auto bottomBound = targetRowIndex + 1;
auto neighborsCounter = 0;
// left to right
for (auto index = leftBound; index <= rightBound; ++index)
if (cellExist(topBound, index, rowCount, columnCount))
neighborsCounter += playingField.at(topBound).at(index)->state() == StateHolder::Enable;
// top to bottom
for (auto index = topBound + 1; index <= bottomBound; ++index)
if (cellExist(index, rightBound, rowCount, columnCount))
neighborsCounter += playingField.at(index).at(rightBound)->state() == StateHolder::Enable;
// right to left
for (auto index = rightBound - 1; index >= leftBound; --index)
if (cellExist(bottomBound, index, rowCount, columnCount))
neighborsCounter += playingField.at(bottomBound).at(index)->state() == StateHolder::Enable;
// bottom to top
for (auto index = bottomBound - 1; index > topBound; --index)
if (cellExist(index, leftBound, rowCount, columnCount))
neighborsCounter += playingField.at(index).at(leftBound)->state() == StateHolder::Enable;
return neighborsCounter;
}
std::vector<StateDiff> LifeGameStateUpdater::updateState(const BinaryField& playingField)
{
const auto rowCount = playingField.size();
const auto columnCount = playingField.at(0).size();
std::vector<StateDiff> stateDiffs;
for (auto rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
for (auto columnIndex = 0; columnIndex < columnCount; ++columnIndex) {
const auto neighborsCount = aliveNeighborsCount(playingField, rowIndex, columnIndex);
const auto previousState = *playingField.at(rowIndex).at(columnIndex);
const auto updatedState = [neighborsCount, previousState]() {
const auto currentCellAlive = previousState.state() == StateHolder::Enable;
static const auto lowBoundAliveCondition = 2;
static const auto upperBoundAliveCondition = 3;
if (currentCellAlive) {
const auto liveContinue = neighborsCount >= lowBoundAliveCondition && neighborsCount <= upperBoundAliveCondition;
return BinaryState(liveContinue ? StateHolder::Enable : StateHolder::Disable);
} else {
const auto liveGenerate = neighborsCount == upperBoundAliveCondition;
return BinaryState(liveGenerate ? StateHolder::Enable : StateHolder::Disable);
}
}();
if (previousState != updatedState) {
StateDiff diff;
diff.previous = previousState;
diff.updated = updatedState;
diff.rowIndex = rowIndex;
diff.columnIndex = columnIndex;
stateDiffs.push_back(diff);
}
}
}
return stateDiffs;
}