-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlife.cpp
More file actions
143 lines (129 loc) · 4.11 KB
/
Copy pathlife.cpp
File metadata and controls
143 lines (129 loc) · 4.11 KB
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
#include "life.h"
#include <QRandomGenerator>
#include <QTimer>
#include <QtGlobal>
Life::Life(uint32_t xSize, uint32_t ySize, QObject *parent)
: QObject(parent), m_xSize(xSize), m_ySize(ySize), m_ym(xSize + 2) {
m_space = new uint32_t[xSize * ySize];
m_tmp = new uint8_t[m_ym * (ySize + 2)];
m_tmpNew = new uint8_t[m_ym * (ySize + 2)];
m_virusQueue = 0;
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(playGame()));
}
Life::~Life() {
delete m_tmpNew;
delete m_tmp;
delete m_space;
}
void Life::generateSpace() {
for (uint32_t y = 1; y <= m_ySize; y++)
for (uint32_t x = 1; x <= m_xSize; x++) {
if (QRandomGenerator::global()->bounded(2)) {
// alive
m_tmp[y * m_ym + x] = 1;
} else {
// dead
m_tmp[y * m_ym + x] = 0;
}
}
for (uint32_t y = 1; y <= m_ySize; y++) {
m_tmp[y * m_ym] = m_tmp[y * m_ym + m_xSize];
m_tmp[y * m_ym + m_xSize + 1] = m_tmp[y * m_ym + 1];
}
for (uint32_t x = 1; x <= m_xSize; x++) {
m_tmp[x] = m_tmp[m_ySize * m_ym + x];
m_tmp[(m_ySize + 1) * m_ym + x] = m_tmp[m_ym + x];
}
m_tmp[0] = m_tmp[m_ySize * m_ym + m_xSize];
m_tmp[(m_ySize + 1) * m_ym + m_xSize + 1] = m_tmp[m_ym + 1];
m_tmp[m_xSize + 1] = m_tmp[m_ySize * m_ym + 1];
m_tmp[(m_ySize + 1) * m_ym] = m_tmp[m_ym + m_xSize];
}
void Life::startGame() {
m_timer->stop();
generateSpace();
m_timer->start(10);
}
void Life::stopGame() { m_timer->stop(); }
void Life::addVirus() { m_virusQueue++; }
void Life::addVirus(uint32_t x, uint32_t y) {
if (m_timer->isActive()) {
m_tmp[y * m_ym + x] = 3;
}
}
void Life::addLife(uint32_t x, uint32_t y) {
if (m_timer->isActive()) {
m_tmp[y * m_ym + x] = 1;
}
}
void Life::playGame() {
calcSpace();
drawSpace();
emit sendSpace(m_space, m_xSize, m_ySize);
}
void Life::calcSpace() {
for (uint32_t y = 1; y <= m_ySize; y++)
for (uint32_t x = 1; x <= m_xSize; x++) {
m_tmpNew[y * m_ym + x] = calcCell(x, y);
if (m_virusQueue && m_tmpNew[y * m_ym + x] == 1 &&
QRandomGenerator::global()->bounded(m_ySize * m_xSize) == 0) {
m_virusQueue--;
m_tmpNew[y * m_ym + x] = 3;
}
}
for (uint32_t y = 1; y <= m_ySize; y++) {
m_tmpNew[y * m_ym] = m_tmpNew[y * m_ym + m_xSize];
m_tmpNew[y * m_ym + m_xSize + 1] = m_tmpNew[y * m_ym + 1];
}
for (uint32_t x = 1; x <= m_xSize; x++) {
m_tmpNew[x] = m_tmpNew[m_ySize * m_ym + x];
m_tmpNew[(m_ySize + 1) * m_ym + x] = m_tmpNew[m_ym + x];
}
m_tmpNew[0] = m_tmpNew[m_ySize * m_ym + m_xSize];
m_tmpNew[(m_ySize + 1) * m_ym + m_xSize + 1] = m_tmpNew[m_ym + 1];
m_tmpNew[m_xSize + 1] = m_tmpNew[m_ySize * m_ym + 1];
m_tmpNew[(m_ySize + 1) * m_ym] = m_tmpNew[m_ym + m_xSize];
std::swap(m_tmpNew, m_tmp);
}
uint8_t Life::calcCell(uint32_t x, uint32_t y) {
uint32_t x_l = x - 1;
uint32_t x_r = x + 1;
uint32_t y_u = y - 1;
uint32_t y_d = y + 1;
uint32_t res = 0;
uint32_t virus = 0;
res += (m_tmp[y_u * m_ym + x_l] & 1) + (m_tmp[y_u * m_ym + x] & 1) +
(m_tmp[y_u * m_ym + x_r] & 1) + (m_tmp[y * m_ym + x_l] & 1) +
(m_tmp[y * m_ym + x] & 1) + (m_tmp[y * m_ym + x_r] & 1) +
(m_tmp[y_d * m_ym + x_l] & 1) + (m_tmp[y_d * m_ym + x] & 1) +
(m_tmp[y_d * m_ym + x_r] & 1);
virus += (m_tmp[y_u * m_ym + x_l] & 2) + (m_tmp[y_u * m_ym + x] & 2) +
(m_tmp[y_u * m_ym + x_r] & 2) + (m_tmp[y * m_ym + x_l] & 2) +
(m_tmp[y * m_ym + x] & 2) + (m_tmp[y * m_ym + x_r] & 2) +
(m_tmp[y_d * m_ym + x_l] & 2) + (m_tmp[y_d * m_ym + x] & 2) +
(m_tmp[y_d * m_ym + x_r] & 2);
if (res == 3 || (res == 4 && m_tmp[y * m_ym + x])) {
return virus ? 3 : 1;
}
return 0;
}
void Life::drawSpace() {
for (uint32_t y = 1; y <= m_ySize; y++)
for (uint32_t x = 1; x <= m_xSize; x++) {
uint32_t &color = m_space[(y - 1) * m_xSize + x - 1];
uint8_t &cell = m_tmp[y * m_ym + x];
if (cell == 3) {
color = 0xffff0000;
}
if (cell == 1) {
color |= 0xff00ff00;
if ((color & 0xff) != 0xff) {
color++;
}
}
if (cell == 0) {
color = 0xff000000;
}
}
}