Skip to content

Commit 15d3f27

Browse files
committed
7 цветов клеток
1 parent 8dd0930 commit 15d3f27

File tree

4 files changed

+98
-128
lines changed

4 files changed

+98
-128
lines changed

game/GPUAutomaton.cpp

+67-114
Original file line numberDiff line numberDiff line change
@@ -83,27 +83,73 @@ int countLiveNeighbors(ivec2 pos, int targetType) {
8383
}
8484
8585
int determineNewType(ivec2 pos) {
86-
int greenNeighbors = countLiveNeighbors(pos, 1); // Зелёные
87-
int redNeighbors = countLiveNeighbors(pos, 2); // Красные
88-
int blueNeighbors = countLiveNeighbors(pos, 3); // Синие
89-
90-
if (greenNeighbors > redNeighbors && greenNeighbors > blueNeighbors) {
91-
return 1; // Зелёный
92-
} else if (redNeighbors > greenNeighbors && redNeighbors > blueNeighbors) {
93-
return 2; // Красный
94-
} else if (blueNeighbors > greenNeighbors && blueNeighbors > redNeighbors) {
95-
return 3; // Синий
96-
} else if (greenNeighbors == redNeighbors && greenNeighbors > blueNeighbors) {
97-
return 4; // Жёлтый (зелёный = красный)
98-
} else if (greenNeighbors == blueNeighbors && greenNeighbors > redNeighbors) {
99-
return 5; // Оранжевый (зелёный = синий)
100-
} else if (redNeighbors == blueNeighbors && redNeighbors > greenNeighbors) {
101-
return 6; // Фиолетовый (красный = синий)
102-
} else { // Все три равны
103-
return 7; // Белый (зелёный = красный = синий)
86+
int neighborsCount[8];
87+
for (int i = 1; i <= 7; i++) {
88+
neighborsCount[i] = countLiveNeighbors(pos, i);
89+
}
90+
91+
int maxCount = 0;
92+
int equalTypes[8];
93+
int equalCount = 0;
94+
for (int i = 1; i <= 7; i++) {
95+
if (neighborsCount[i] > maxCount) {
96+
maxCount = neighborsCount[i];
97+
equalCount = 0;
98+
equalTypes[equalCount] = i; // Сохраняем новый макс. тип
99+
equalCount++;
100+
} else if (neighborsCount[i] == maxCount && maxCount != 0) {
101+
equalTypes[equalCount] = i; // Сохраняем равный тип
102+
equalCount++;
103+
}
104+
}
105+
if(maxCount == 0) return 0; //если нет соседей, то умирает
106+
107+
if (equalCount > 1) {
108+
int randomIndex = int(float(equalCount) * fract(sin(dot(pos, vec2(12.9898, 78.233))) * 43758.5453));
109+
return equalTypes[randomIndex]; // Возвращаем случайный тип из равных
110+
} else {
111+
return equalTypes[0]; // Возвращаем единственный максимальный тип
104112
}
105113
}
106114
115+
// Метод для генерации цвета на основе типа клетки.
116+
vec4 getColorByType(int type, int currentState) {
117+
if (type == 0) {
118+
return vec4(0.05, 0.05, 0.08, 0.0); // Мертвая клетка
119+
}
120+
if (type < 0) {
121+
return vec4(0.0, 0.0, 0.0, 0.0); // Пустая клетка
122+
}
123+
124+
125+
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
126+
float increase = 0.02;
127+
128+
int t = type;
129+
int r = (t / 4) % 2;
130+
int g = (t / 2) % 2;
131+
int b = (t / 1) % 2;
132+
133+
color.r = float(r);
134+
color.g = float(g);
135+
color.b = float(b);
136+
137+
if(currentState > 0 && currentState == type){
138+
vec4 currentColor = colors[gl_GlobalInvocationID.y * gridSize.x + gl_GlobalInvocationID.x];
139+
color.r = min(currentColor.r + increase, color.r);
140+
color.g = min(currentColor.g + increase, color.g);
141+
color.b = min(currentColor.b + increase, color.b);
142+
}
143+
if (type > 7){
144+
color = vec4(1.0,1.0,1.0,0.0);
145+
}
146+
if(type > 0){
147+
color = clamp(color,vec4(0,0,0,0),vec4(1,1,1,0));
148+
}
149+
return color;
150+
}
151+
152+
107153
void main() {
108154
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
109155
if (pos.x >= gridSize.x || pos.y >= gridSize.y) return;
@@ -129,103 +175,15 @@ void main() {
129175
} else {
130176
nextState = 0; // Умирает
131177
}
132-
} else if (currentState == 0) { // Мёртвая клетка
178+
} else if (currentState <= 0) { // Мёртвая клетка
133179
if (neighbors == birth) {
134180
nextState = determineNewType(pos); // Оживает с типом
135181
}
136182
}
137183
}
138184
139185
next[index] = nextState;
140-
141-
// Обновляем цвета в зависимости от типа
142-
if (nextState == 1) { // Зелёный
143-
if (currentState == 1) {
144-
vec4 currentColor = colors[index];
145-
colors[index] = vec4(
146-
min(currentColor.r + 0.02, 0.02),
147-
min(currentColor.g + 0.02, 1.0),
148-
min(currentColor.b + 0.02, 0.02),
149-
1.0
150-
);
151-
} else {
152-
colors[index] = vec4(0.0, 0.5, 0.0, 1.0); // Начальный зелёный
153-
}
154-
} else if (nextState == 2) { // Красный
155-
if (currentState == 2) {
156-
vec4 currentColor = colors[index];
157-
colors[index] = vec4(
158-
min(currentColor.r + 0.02, 1.0),
159-
min(currentColor.g + 0.02, 0.02),
160-
min(currentColor.b + 0.02, 0.02),
161-
1.0
162-
);
163-
} else {
164-
colors[index] = vec4(0.5, 0.0, 0.0, 1.0); // Начальный красный
165-
}
166-
} else if (nextState == 3) { // Синий
167-
if (currentState == 3) {
168-
vec4 currentColor = colors[index];
169-
colors[index] = vec4(
170-
min(currentColor.r + 0.02, 0.02),
171-
min(currentColor.g + 0.02, 0.02),
172-
min(currentColor.b + 0.02, 1.0),
173-
1.0
174-
);
175-
} else {
176-
colors[index] = vec4(0.0, 0.0, 0.5, 1.0); // Начальный синий
177-
}
178-
} else if (nextState == 4) { // Жёлтый (зелёный = красный)
179-
if (currentState == 4) {
180-
vec4 currentColor = colors[index];
181-
colors[index] = vec4(
182-
min(currentColor.r + 0.02, 1.0),
183-
min(currentColor.g + 0.02, 1.0),
184-
min(currentColor.b + 0.02, 0.02),
185-
1.0
186-
);
187-
} else {
188-
colors[index] = vec4(0.5, 0.5, 0.0, 1.0); // Начальный жёлтый
189-
}
190-
} else if (nextState == 5) { // Оранжевый (зелёный = синий)
191-
if (currentState == 5) {
192-
vec4 currentColor = colors[index];
193-
colors[index] = vec4(
194-
min(currentColor.r + 0.02, 1.0),
195-
min(currentColor.g + 0.02, 0.02),
196-
min(currentColor.b + 0.02, 1.0),
197-
1.0
198-
);
199-
} else {
200-
colors[index] = vec4(0.5, 0.0, 0.5, 1.0); // Начальный оранжевый
201-
}
202-
} else if (nextState == 6) { // Фиолетовый (красный = синий)
203-
if (currentState == 6) {
204-
vec4 currentColor = colors[index];
205-
colors[index] = vec4(
206-
min(currentColor.r + 0.02, 1.0),
207-
min(currentColor.g + 0.02, 0.02),
208-
min(currentColor.b + 0.02, 1.0),
209-
1.0
210-
);
211-
} else {
212-
colors[index] = vec4(0.0, 0.5, 0.5, 1.0); // Начальный фиолетовый
213-
}
214-
} else if (nextState == 7) { // Белый (зелёный = красный = синий)
215-
if (currentState == 7) {
216-
vec4 currentColor = colors[index];
217-
colors[index] = vec4(
218-
min(currentColor.r + 0.02, 1.0),
219-
min(currentColor.g + 0.02, 1.0),
220-
min(currentColor.b + 0.02, 1.0),
221-
1.0
222-
);
223-
} else {
224-
colors[index] = vec4(1.0, 1.0, 1.0, 1.0); // Начальный белый
225-
}
226-
} else if (currentState > 0) { // Клетка умерла
227-
colors[index] = vec4(0.05, 0.05, 0.08, 0.0);
228-
}
186+
colors[index] = getColorByType(nextState, currentState);
229187
}
230188
231189
)";
@@ -365,7 +323,7 @@ void main() {
365323
colors[index] = vec4(0.9, 0.9, 0.9, 1.0);
366324
}
367325
} else {
368-
cells[index] = 0; // Мёртвая клетка
326+
cells[index] = -1; // пустая клетка
369327
colors[index] = vec4(0.0, 0.0, 0.0, 0.0); // Чёрный
370328
}
371329
}
@@ -474,11 +432,6 @@ void GPUAutomaton::SetCellState(int x, int y, int state) {
474432
std::cerr << "SetCellState: Invalid coordinates (" << x << ", " << y << ")" << std::endl;
475433
return;
476434
}
477-
if (state != 0 && state != 1) {
478-
std::cerr << "SetCellState: Invalid state value (" << state << "). Use 0 (dead) or 1 (alive)." << std::endl;
479-
return;
480-
}
481-
482435
int index = y * gridWidth + x;
483436
int stateData = state;
484437
//glFinish();

game/GameController.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ GameController::GameController(int width, int height, float cellSize)
77
isRunning(false), showGrid(true), showUI(true), isWorldToroidal(true),
88
isPatternPlacementMode(false), isTurboBoost(false), currentPatternRotator(0),
99
isSelectionActive(false), rendererProvider(nullptr) {
10-
//gameAutomaton = new GPUAutomaton(grid.getWidth(), grid.getHeight()); // Пока используем GPUAutomaton
11-
gameAutomaton = new EcosystemAutomaton(grid.getWidth(), grid.getHeight());
10+
gameAutomaton = new GPUAutomaton(grid.getWidth(), grid.getHeight()); // Пока используем GPUAutomaton
11+
//gameAutomaton = new EcosystemAutomaton(grid.getWidth(), grid.getHeight());
1212

1313
std::srand(static_cast<unsigned int>(std::time(nullptr)));
1414
grid.SetGPUAutomaton(gameAutomaton);
@@ -42,7 +42,7 @@ void GameController::placePattern(int startX, int startY, const Pattern& pattern
4242
grid.SetCellType(startX + (patternWidth - 1 - x), startY + (patternHeight - 1 - y), cellType);
4343
}
4444
else {
45-
grid.setCellState(startX + (patternWidth - 1 - x), startY + (patternHeight - 1 - y), 0);
45+
grid.SetCellType(startX + (patternWidth - 1 - x), startY + (patternHeight - 1 - y), -1);
4646
grid.setCellColor(startX + (patternWidth - 1 - x), startY + (patternHeight - 1 - y), 0.1f, 0.1f, 0.2f);
4747
}
4848
}

rendering/PatternInserterRenderer.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,17 @@ void PatternInserterRenderer::UpdateBuffers() {
4747

4848
float cellSize = pGameController->getCellSize();
4949
float r, g, b;
50-
if (cellType == 1) { r = 0.0f; g = 0.5f; b = 0.0f; } // Зелёный
51-
else if (cellType == 2) { r = 0.5f; g = 0.0f; b = 0.0f; } // Красный
52-
else if (cellType == 3) { r = 0.0f; g = 0.0f; b = 0.5f; } // Синий
53-
else if (cellType == 4) { r = 0.5f; g = 0.5f; b = 0.0f; } // Жёлтый
54-
else if (cellType == 5) { r = 0.5f; g = 0.0f; b = 0.5f; } // Оранжевый
55-
else if (cellType == 6) { r = 0.0f; g = 0.5f; b = 0.5f; } // Фиолетовый
56-
else { r = 1.0f; g = 1.0f; b = 1.0f; } // Белый (cellType == 7)
50+
//if (cellType == 1) { r = 0.0f; g = 0.5f; b = 0.0f; } // Зелёный
51+
//else if (cellType == 2) { r = 0.5f; g = 0.0f; b = 0.0f; } // Красный
52+
//else if (cellType == 3) { r = 0.0f; g = 0.0f; b = 0.5f; } // Синий
53+
//else if (cellType == 4) { r = 0.5f; g = 0.5f; b = 0.0f; } // Жёлтый
54+
//else if (cellType == 5) { r = 0.5f; g = 0.0f; b = 0.5f; } // Оранжевый
55+
//else if (cellType == 6) { r = 0.0f; g = 0.5f; b = 0.5f; } // Фиолетовый
56+
//else { r = 1.0f; g = 1.0f; b = 1.0f; } // Белый (cellType == 7)
57+
r = (float)((cellType / 4) % 2) / 2.0f; // Делим на 2.0f
58+
g = (float)((cellType / 2) % 2) / 2.0f; // Делим на 2.0f
59+
b = (float)((cellType / 1) % 2) / 2.0f; // Делим на 2.0f
60+
5761

5862
float inset = 0.2f; // Отступ 0.2 от края клетки (на каждую сторону)
5963

shader/ecosystemShader.hlsl

+17-4
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,27 @@ int determineNewType(ivec2 pos) {
6565
}
6666

6767
int maxCount = 0;
68-
int maxType = 0;
68+
int equalTypes[8];
69+
int equalCount = 0;
6970
for (int i = 1; i <= 7; i++) {
7071
if (neighborsCount[i] > maxCount) {
7172
maxCount = neighborsCount[i];
72-
maxType = i;
73+
equalCount = 0;
74+
equalTypes[equalCount] = i; // Сохраняем новый макс. тип
75+
equalCount++;
76+
} else if (neighborsCount[i] == maxCount && maxCount != 0) {
77+
equalTypes[equalCount] = i; // Сохраняем равный тип
78+
equalCount++;
7379
}
7480
}
75-
return maxType;
81+
if(maxCount == 0) return 0; //если нет соседей, то умирает
82+
83+
if (equalCount > 1) {
84+
int randomIndex = int(float(equalCount) * fract(sin(dot(pos, vec2(12.9898, 78.233))) * 43758.5453));
85+
return equalTypes[randomIndex]; // Возвращаем случайный тип из равных
86+
} else {
87+
return equalTypes[0]; // Возвращаем единственный максимальный тип
88+
}
7689
}
7790

7891
// Метод для генерации цвета на основе типа клетки.
@@ -138,7 +151,7 @@ void main() {
138151
} else {
139152
nextState = 0; // Умирает
140153
}
141-
} else if (currentState == 0) { // Мёртвая клетка
154+
} else if (currentState <= 0) { // Мёртвая клетка
142155
if (neighbors == birth) {
143156
nextState = determineNewType(pos); // Оживает с типом
144157
}

0 commit comments

Comments
 (0)