Skip to content

Commit 3e36697

Browse files
committed
Загрузка и сохранение мира. Пока только в текстовом формате
1 parent 4c74ffe commit 3e36697

10 files changed

+157
-91
lines changed

README.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,12 @@ git submodule update --recursive --remote
156156

157157
## Известные проблемы
158158

159-
- Производительность может ухудшаться на очень больших сетках из-за сложности 3D визуализации и вычисления.
159+
- Производительность может ухудшаться на очень больших сетках из-за сложности 3D визуализации и вычисления живых и неживых клеток.
160160

161161
### Будущие улучшения
162162

163163
- [ ] Реализация различных наборов правил для "Жизни".
164-
- [ ] Добавление дополнительных интерактивных элементов управления для изменения размера сетки, размера клетки и т.д.
164+
- [x] Управления изменения размера сетки.
165165
- [x] Оптимизация рендеринга для лучшей производительности на больших сетках или более сложных узорах.
166166

167167
## От автор
@@ -171,7 +171,8 @@ git submodule update --recursive --remote
171171
- Создайте форк репозитория.
172172
- Сделайте изменения в своей копии.
173173
- Отправьте pull request с описанием изменений.
174-
- Связатся со мной вы можете в телеграмм [@AsuRaHan](https://t.me/AsuRaHan)
174+
- Связатся со мной вы можете в [телеграмм](https://t.me/AsuRaHan)
175+
- Собираю донаты [тут](https://boosty.to/asurahan/single-payment/donation/677381/target?share=target_link)
175176

176177
## Что читал кем вдохновлялся и где черпал информацию
177178

game/GameController.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#include "GameController.h"
22

33
GameController::GameController(int width, int height, float cellSize)
4-
: grid(width, height), gameOfLife(grid), cellSize(cellSize), isRunning(false) {
4+
: grid(width, height), gameOfLife(grid), cellSize(cellSize), isRunning(false), showGrid(true) {
55
currentPattern = glider;
66
std::srand(static_cast<unsigned int>(std::time(nullptr))); // Èíèöèàëèçàöèÿ ãåíåðàòîðà ñëó÷àéíûõ ÷èñåë
77
}
88

9-
void GameController::initializeGrid() {
9+
void GameController::randomizeGrid() {
1010

1111
std::random_device rd; // Òîëüêî äëÿ èíèöèàëèçàöèè ãåíåðàòîðà
1212
std::mt19937 gen(rd()); // Ñòàíäàðòíûé ìåðñåííîâñêèé òâèñòåð
@@ -104,11 +104,11 @@ void GameController::clearGrid() {
104104

105105
void GameController::update(float deltaTime) {
106106
if (isRunning) {
107-
frameTimeAccumulator += deltaTime;
108-
if (frameTimeAccumulator >= simulationSpeed) {
107+
//frameTimeAccumulator += deltaTime;
108+
//if (frameTimeAccumulator >= simulationSpeed) {
109109
gameOfLife.nextGeneration();
110-
frameTimeAccumulator -= simulationSpeed;
111-
}
110+
// frameTimeAccumulator -= simulationSpeed;
111+
//}
112112
}
113113
}
114114

game/GameController.h

+18-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66
#include "GameOfLife.h"
77
#include "Grid.h"
8+
#include "GameStateManager.h"
89
#include <random> // Äëÿ ãåíåðàöèè ñëó÷àéíûõ ÷èñåë
910
#include <string>
1011
#include <fstream>
@@ -20,7 +21,8 @@ class GameController {
2021
GameOfLife gameOfLife;
2122
float cellSize; // Ðàçìåð êàæäîé êëåòêè â ïèêñåëÿõ
2223
bool isRunning; // Ôëàã, ïîêàçûâàåò, çàïóùåíà ëè ñèìóëÿöèÿ
23-
float simulationSpeed = 0.001f; // Çíà÷åíèå 1.0f ìîæåò ñîîòâåòñòâîâàòü îäíîé ñåêóíäå ðåàëüíîãî âðåìåíè
24+
bool showGrid;
25+
float simulationSpeed = 0.01f; // Çíà÷åíèå 1.0f ìîæåò ñîîòâåòñòâîâàòü îäíîé ñåêóíäå ðåàëüíîãî âðåìåíè
2426
float frameTimeAccumulator = 0.0f;
2527

2628
// Îïðåäåëèì òèï ôèãóðû êàê äâóìåðíûé ìàññèâ
@@ -165,7 +167,7 @@ class GameController {
165167
public:
166168

167169
GameController(int width, int height, float cellSize = 0.5f);
168-
void initializeGrid();
170+
void randomizeGrid();
169171
void placePattern(int startX, int startY, const Pattern& pattern);
170172
void randomizeGrid(float density);
171173
void clearGrid();
@@ -180,6 +182,8 @@ class GameController {
180182
float getCellSize() const { return cellSize; }
181183
int getGridWidth() const { return grid.getWidth(); }
182184
int getGridHeight() const { return grid.getHeight(); }
185+
bool getShowGrid() const {return showGrid;};
186+
void setShowGrid(bool isShow) {showGrid = isShow;};
183187

184188
bool getCellState(int x, int y) const;
185189
const Grid& getGrid() const { return grid; }
@@ -190,7 +194,18 @@ class GameController {
190194
void setCurrentPattern(int patternNumber);
191195
void PlacePattern(int startX, int startY);
192196
void setWoldToroidal(bool wt) { gameOfLife.setWoldToroidal( wt); };
193-
bool getWoldToroidal() { return gameOfLife.getWoldToroidal(); };
197+
bool getWoldToroidal() const { return gameOfLife.getWoldToroidal(); };
194198
void setSimulationSpeed(float speed);
199+
200+
// Íîâûå ìåòîäû äëÿ ñîõðàíåíèÿ è çàãðóçêè ñîñòîÿíèÿ èãðû
201+
bool saveGameState(const std::string& filename) const {
202+
return GameStateManager::saveGameState(grid, filename);
203+
}
204+
bool loadGameState(const std::string& filename) {
205+
return GameStateManager::loadGameState(grid, filename);
206+
}
207+
bool saveGameStateCSV(const std::string& filename) const {
208+
return GameStateManager::saveGameStateCSV(grid, filename);
209+
}
195210
};
196211
#endif // GAMECONTROLLER_H_

game/GameStateManager.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,17 @@ bool GameStateManager::saveGameState(const Grid& grid, const std::string& filena
2525
}
2626

2727
bool GameStateManager::loadGameState(Grid& grid, const std::string& filename) {
28+
2829
std::ifstream file(filename);
2930
if (!file.is_open()) {
30-
std::cerr << "Íå óäàëîñü îòêðûòü ôàéë äëÿ ÷òåíèÿ: " << filename << std::endl;
31+
char buffer[256];
32+
strerror_s(buffer, sizeof(buffer), errno);
33+
std::cerr << "Íå óäàëîñü îòêðûòü ôàéë äëÿ ÷òåíèÿ: " << filename << ", îøèáêà: " << buffer << std::endl;
3134
return false;
3235
}
3336

37+
38+
3439
// ×èòàåì ðàçìåðû
3540
int width, height;
3641
file >> width >> height;
@@ -46,7 +51,15 @@ bool GameStateManager::loadGameState(Grid& grid, const std::string& filename) {
4651
int y = 0;
4752
while (std::getline(file, line) && y < height) {
4853
for (int x = 0; x < std::min(width, (int)line.length()); ++x) {
54+
4955
grid.setCellState(x, y, line[x] == '1');
56+
if (line[x] == '1') {
57+
grid.getCell(x, y).setColor(Vector3d(0.0f, 0.6f, 0.0f));
58+
}
59+
else {
60+
grid.getCell(x, y).setColor(Vector3d(0.0f, 0.0f, 0.0f));
61+
}
62+
5063
}
5164
++y;
5265
}

rendering/Camera.h

+2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ class Camera {
3232

3333
const float* GetViewMatrix() const { return viewMatrix.data(); }
3434
const float* GetProjectionMatrix() const { return projectionMatrix.data(); }
35+
3536
float GetDistance() const;
37+
3638
static constexpr float PI = 3.14159265358979323846f;
3739
static constexpr float MAX_PITCH = 89.0f * PI / 180.0f;
3840

rendering/Renderer.cpp

+17-20
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Renderer::Renderer(int width, int height)
88
}
99

1010
Renderer::~Renderer() {
11-
glDeleteProgram(shaderProgram);
11+
glDeleteProgram(cellShaderProgram);
1212
glDeleteProgram(gridShaderProgram);
1313
glDeleteProgram(debugOverlayShaderProgram);
1414
glDeleteBuffers(1, &cellsVBO);
@@ -25,7 +25,10 @@ void Renderer::SetCamera(const Camera& camera) {
2525
void Renderer::SetGameController(GameController* gameController) {
2626
pGameController = gameController;
2727
LoadShaders();
28-
InitializeVBOs();
28+
29+
InitializeCellsVBOs();
30+
InitializeGridVBOs();
31+
2932
uiController = UIController(pGameController);
3033
uiController.InitializeUI();
3134
}
@@ -36,7 +39,7 @@ void Renderer::SetupOpenGL() {
3639
GL_CHECK(glViewport(0, 0, width, height));
3740
}
3841

39-
void Renderer::InitializeVBOs() {
42+
void Renderer::InitializeCellsVBOs() {
4043
if (!pGameController) return;
4144
int gridWidth = pGameController->getGridWidth();
4245
int gridHeight = pGameController->getGridHeight();
@@ -102,8 +105,6 @@ void Renderer::InitializeVBOs() {
102105
// Îòâÿçûâàåì áóôåðû è VAO
103106
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
104107
GL_CHECK(glBindVertexArray(0));
105-
106-
InitializeGridVBOs();
107108
}
108109

109110
void Renderer::InitializeGridVBOs() {
@@ -116,7 +117,7 @@ void Renderer::InitializeGridVBOs() {
116117

117118
// Îïðåäåëåíèå øàãîâ äëÿ äîïîëíèòåëüíûõ ëèíèé
118119
int minorStep = 10; // Íàïðèìåð, ëèíèè ÷åðåç êàæäûå 10 åäèíèö
119-
int majorStep = 50; // Íàïðèìåð, áîëåå çàìåòíûå ëèíèè ÷åðåç êàæäûå 50 åäèíèö
120+
int majorStep = 100; // Íàïðèìåð, áîëåå çàìåòíûå ëèíèè ÷åðåç êàæäûå 50 åäèíèö
120121

121122
// Ñîçäàíèå ñåòêè
122123
for (int y = 0; y <= gridHeight; ++y) {
@@ -162,7 +163,7 @@ void Renderer::Draw() {
162163

163164
DrawCells();
164165
// Îòðèñîâêà ñåòêè è êëåòîê
165-
if (showGrid)DrawGrid();
166+
if (pGameController->getShowGrid())DrawGrid();
166167
// Òåïåðü èñïîëüçóåì UIController äëÿ îòðèñîâêè UI
167168
uiController.DrawUI();
168169

@@ -179,12 +180,12 @@ void Renderer::DrawGrid() {
179180
// Ïåðåäàåì ìàòðèöû ïðîåêöèè è âèäà â øåéäåðû
180181
GLuint projectionLoc = glGetUniformLocation(gridShaderProgram, "projection");
181182
GLuint viewLoc = glGetUniformLocation(gridShaderProgram, "view");
182-
GLuint cameraDistanceLoc = glGetUniformLocation(gridShaderProgram, "cameraDistance"); // Íîâàÿ uniform äëÿ äèñòàíöèè êàìåðû
183+
GLuint cameraDistanceLoc = glGetUniformLocation(gridShaderProgram, "cameraDistance"); // uniform äëÿ äèñòàíöèè êàìåðû
183184

184185
GL_CHECK(glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, camera.GetProjectionMatrix()));
185186
GL_CHECK(glUniformMatrix4fv(viewLoc, 1, GL_FALSE, camera.GetViewMatrix()));
186187

187-
float cameraDistance = camera.GetDistance(); // Ïðåäïîëàãàåì, ÷òî ó êàìåðû åñòü ìåòîä äëÿ ïîëó÷åíèÿ ðàññòîÿíèÿ
188+
float cameraDistance = camera.GetDistance();
188189
GL_CHECK(glUniform1f(cameraDistanceLoc, cameraDistance));
189190

190191
// Ñâÿçûâàåì VAO ñåòêè
@@ -217,12 +218,12 @@ void Renderer::DrawCells() {
217218
GL_CHECK(glUnmapBuffer(GL_ARRAY_BUFFER));
218219
}
219220

220-
GL_CHECK(glUseProgram(shaderProgram));
221+
GL_CHECK(glUseProgram(cellShaderProgram));
221222

222223
// Óñòàíàâëèâàåì uniform ïåðåìåííûå
223-
GLuint projectionLoc = glGetUniformLocation(shaderProgram, "projection");
224-
GLuint viewLoc = glGetUniformLocation(shaderProgram, "view");
225-
GLuint cellSizeLoc = glGetUniformLocation(shaderProgram, "cellSize");
224+
GLuint projectionLoc = glGetUniformLocation(cellShaderProgram, "projection");
225+
GLuint viewLoc = glGetUniformLocation(cellShaderProgram, "view");
226+
GLuint cellSizeLoc = glGetUniformLocation(cellShaderProgram, "cellSize");
226227

227228
GL_CHECK(glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, camera.GetProjectionMatrix()));
228229
GL_CHECK(glUniformMatrix4fv(viewLoc, 1, GL_FALSE, camera.GetViewMatrix()));
@@ -304,7 +305,7 @@ void main()
304305
shaderManager.loadVertexShader("cellVertexShader", vertexShaderSource.c_str());
305306
shaderManager.loadFragmentShader("cellFragmentShader", fragmentShaderSource.c_str());
306307
shaderManager.linkProgram("cellShaderProgram", "cellVertexShader", "cellFragmentShader");
307-
shaderProgram = shaderManager.getProgram("cellShaderProgram");
308+
cellShaderProgram = shaderManager.getProgram("cellShaderProgram");
308309

309310
}
310311

@@ -335,7 +336,7 @@ void main()
335336
drawMinor = (cameraDistance > 100.0) ? 0.0 : 1.0; // Ñàìûå ìåëêèå ëèíèè âèäíû, åñëè êàìåðà áëèæå 100 åäèíèö
336337
337338
// Óñòàíàâëèâàåì âèäèìîñòü äëÿ ñðåäíèõ ëèíèé
338-
drawMedium = (cameraDistance > 150.0) ? 0.0 : 1.0; // Ñðåäíèå ëèíèè âèäíû, åñëè êàìåðà áëèæå 150 åäèíèö
339+
drawMedium = (cameraDistance > 250.0) ? 0.0 : 1.0; // Ñðåäíèå ëèíèè âèäíû, åñëè êàìåðà áëèæå 150 åäèíèö
339340
}
340341
)";
341342

@@ -375,9 +376,5 @@ void Renderer::RebuildGameField() {
375376
glDeleteBuffers(1, &cellInstanceVBO);
376377
glDeleteBuffers(1, &gridVBO);
377378

378-
InitializeVBOs(); // Ïåðåñòðàèâàåì áóôåðû
379-
}
380-
381-
void Renderer::initializeUI() {
382-
379+
InitializeGridVBOs(); // Ïåðåñòðàèâàåì áóôåðû
383380
}

rendering/Renderer.h

+4-18
Original file line numberDiff line numberDiff line change
@@ -22,51 +22,38 @@ class Renderer {
2222
Camera& GetCamera() { return camera; }
2323

2424
void SetGameController(GameController* gameController);
25-
26-
2725
void Draw();
28-
2926
void OnWindowResize(int newWidth, int newHeight);
30-
3127
void MoveCamera(float dx, float dy, float dz);
32-
3328
int getWindowWidth() const { return width; }
3429
int getWindowHeight() const { return height; }
35-
bool getShowGrid() { return showGrid; };
36-
void setShowGrid(bool show) { showGrid = show; };
37-
3830
void RebuildGameField(); // ìåòîä äëÿ ïåðåñòðîéêè èãðîâîãî ïîëÿ
3931

40-
void initializeUI();
41-
4232
private:
4333
int width, height;
4434
Camera camera;
4535
GameController* pGameController;
4636
UIController uiController;
47-
48-
bool showGrid = true;
49-
ShaderManager shaderManager; // Äîáàâëÿåì ShaderManager
37+
ShaderManager shaderManager;
5038

5139

5240
void InitializeGridVBOs();
5341
GLuint gridVBO;
5442
GLuint gridVAO;
5543

56-
void InitializeVBOs();
44+
void InitializeCellsVBOs();
5745
GLuint cellsVBO;
5846
GLuint cellsVAO;
5947

6048
std::vector<GLfloat> gridVertices;
61-
std::vector<GLfloat> cellVertices;
62-
6349
struct CellInstance {
6450
float x, y; // Ïîçèöèÿ êëåòêè
6551
Vector3d color; // Öâåò êëåòêè
6652
};
6753
GLuint cellInstanceVBO;
6854
std::vector<CellInstance> cellInstances;
69-
GLuint shaderProgram;
55+
56+
GLuint cellShaderProgram;
7057
// äëÿ øåéäåðîâ ñåòêè
7158
GLuint gridShaderProgram;
7259

@@ -80,6 +67,5 @@ class Renderer {
8067
void LoadShaders();
8168
void LoadCellShaders();
8269
void LoadGridShaders();
83-
8470
};
8571
#endif // RENDERER_H_

0 commit comments

Comments
 (0)