-
Notifications
You must be signed in to change notification settings - Fork 3
/
Board.h
185 lines (152 loc) · 4.23 KB
/
Board.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
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#pragma once
#include <mutex>
#include <vector>
#include <gsl/gsl>
#include "Shape.h"
#include "Cell.h"
struct GridPoint
{
uint16_t x;
uint16_t y;
bool operator==(const GridPoint& other) const noexcept
{
return x == other.x && y == other.y;
}
};
enum class BoardRules : uint8_t
{
FastConway = 1,
Conway,
DayAndNight,
LifeWithoutDeath,
BriansBrain,
Seeds,
Highlife
};
// for visualization purposes (0,0) is the top left.
// as x increases move right, as y increases move down
class Board
{
public:
Board() noexcept;
~Board() = default;
// move/copy constuct
Board(Board&& b) = delete;
Board(Board& b) = delete;
// no need to assign one board to another board
Board& operator=(Board&& b) = delete;
Board& operator=(Board& b) = delete;
[[nodiscard]] const Cell& GetCell(uint16_t x, uint16_t y) const
{
return _cells.at(x + (y * _width));
}
[[nodiscard]] Cell& GetCell(uint16_t x, uint16_t y)
{
return _cells.at(x + (y * _width));
}
[[nodiscard]] bool Alive(uint16_t x, uint16_t y) const noexcept
{
return GetCell(x,y).GetState() != Cell::State::Dead;
}
void Resize(uint16_t width, uint16_t height, uint16_t maxage);
void RandomizeBoard(float alivepct, uint16_t maxage);
void TurnCellOn(GridPoint g, bool on);
void Update(BoardRules rules);
bool CopyShape(Shape& shape, uint16_t startX, uint16_t startY);
void PrintBoard();
// getters
void MaxAge(uint16_t maxage) noexcept
{
_maxage = maxage;
}
[[nodiscard]] uint16_t MaxAge() const noexcept
{
return _maxage;
}
void OldAge(uint32_t age) noexcept
{
_OldAge = age;
}
[[nodiscard]] uint32_t GetOldAge() const noexcept
{
return _OldAge;
}
[[nodiscard]] uint32_t GetDeadCount() const noexcept
{
return _numDead;
}
[[nodiscard]] uint32_t GetLiveCount() const noexcept
{
return _numLive;
}
[[nodiscard]] uint32_t GetBornCount() const noexcept
{
return _numBorn;
}
[[nodiscard]] uint32_t GetOldCount() const noexcept
{
return _numOld;
}
[[nodiscard]] uint32_t GetDyingCount() const noexcept
{
return _numDying;
}
[[nodiscard]] uint32_t Generation() const noexcept
{
return _generation;
}
[[nodiscard]] uint16_t Width() const noexcept
{
return _width;
}
[[nodiscard]] uint16_t Height() const noexcept
{
return _height;
}
[[nodiscard]] uint32_t Size() const noexcept
{
return _height * _width;
}
private:
// board updating
// Update calls UpdateRowsWithNextState and FastDetermineNextState
// if you drew the board in between those calls, you'd see the intermediate states e.g. cells born or that will die
// in the next generation many of these are split up to support multithreading
void SetCell(Cell& cell, Cell::State state) noexcept;
void UpdateRowsWithNextState(uint16_t startRow, uint16_t endRow, BoardRules rules);
void FastDetermineNextState(BoardRules rules);
void CountLiveAndDyingNeighbors(uint16_t x, uint16_t y);
[[nodiscard]] uint8_t CountLiveNotDyingNeighbors(uint16_t x, uint16_t y);
void ApplyNextState() noexcept;
// rulesets
void ConwayRules(Cell& cell) const noexcept;
void FastConwayRules(Cell& cell) const noexcept;
void DayAndNightRules(Cell& cell) const noexcept;
void LifeWithoutDeathRules(Cell& cell) const noexcept;
void HighlifeRules(Cell& cell) const noexcept;
void SeedsRules(Cell& cell) const noexcept;
void BriansBrainRules(Cell& cell) const noexcept;
void ResetCounts() noexcept
{
_numDead = 0;
_numLive = 0;
_numBorn = 0;
_numDying = 0;
_numOld = 0;
//_generation = 0;
}
private:
int _threadcount{1};
uint16_t _maxage{ 100 };
std::mutex _lockboard;
std::vector<Cell> _cells;
uint16_t _width{ 0 };
uint16_t _height{ 0 };
uint32_t _generation{ 0 };
uint32_t _numDead{ 0 };
uint32_t _numLive{ 0 };
uint32_t _numBorn{ 0 };
uint32_t _numOld{ 0 };
uint32_t _numDying{ 0 };
uint32_t _OldAge{ 0xFFFFFFFF };
};