From ce2576e9764b9ca6a91c06031e2eaf81b9e63abf Mon Sep 17 00:00:00 2001 From: leca Date: Wed, 28 Aug 2024 21:18:40 +0300 Subject: [PATCH] first commit --- Makefile | 2 + main.cpp | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 Makefile create mode 100644 main.cpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b461dd0 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +main: + g++ main.cpp -lsfml-window -lsfml-graphics -lsfml-system -o life diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..763bebd --- /dev/null +++ b/main.cpp @@ -0,0 +1,186 @@ +#include +#include +#include + +#define ZOOM 10 + +using namespace std; +using namespace sf; + +struct crd { + int x, y; +}; + +int countNeighbors (int x, int y, vector>* board); +bool willItSurvive (vector survive, int neighborCount); +bool willItBeBorn (vector birth, int neighborCount); +void check (int width, int height, vector* willBeBorn, vector* willBeDead, vector>* board); +void render (vector>* board, RenderWindow* win); +void nextStep (vector* willBeBorn, vector* willBeDead, vector>* board); + +int main (int argc, char* argv[]) { + if (argc < 3) { + printf("Usage: %s [width] [height]", argv[0]); + exit(-1); + } + + const int width = atoi(argv[1]); + const int height = atoi(argv[2]); + int fps = 60; + bool pause = false; + vector> board = {}; + vector willBeBorn = {}; + vector willBeDead = {}; + + for (int i = 0; i < height / ZOOM; i ++) { + board.push_back({}); + for (int j = 0; j < width / ZOOM; j ++) { + board[i].push_back(0); + } + } + + RenderWindow win(VideoMode(width, height), "Conway's game of life sfml"); + win.setFramerateLimit(fps); + win.display(); + while (win.isOpen()) { + + if (!pause) { + check(width / ZOOM, height / ZOOM, &willBeBorn, &willBeDead, &board); + render(&board, &win); + nextStep(&willBeBorn, &willBeDead, &board); + } else { + render(&board, &win); + } + Event e; + while(win.pollEvent(e)) { + switch (e.type) { + case Event::Closed: + win.close(); + break; + case Event::MouseWheelMoved: + if (e.mouseWheel.delta < 0 && fps > 1) fps --; + if (e.mouseWheel.delta > 0) fps ++; + break; + case Event::KeyPressed: + if (e.key.code == sf::Keyboard::P) { + pause = !pause; + } + if (e.key.code == sf::Keyboard::C) { + for (int i = 0; i < (int)board.size(); i ++) { + for (int j = 0; j < (int)board[0].size(); j ++) { + board[i][j] = 0; + } + } + } + if (e.key.code == sf::Keyboard::R) { + for (int i = 0; i < (int)board.size(); i ++) { + for (int j = 0; j < (int)board[0].size(); j ++) { + if (i % 2 != 0 || j % 2 != 0) { + board[i][j] = 1; + } else { + // board[i][j] = 0; + } + } + } + } + break; + } + } + if (Mouse::isButtonPressed(Mouse::Left)) { + int mouseX = Mouse::getPosition(win).x / ZOOM, mouseY = Mouse::getPosition(win).y / ZOOM; + if (!(mouseX < 0 + || mouseX > (int)board[0].size() + || mouseY < 0 + || mouseY > (int)board.size()) + ) board[mouseY][mouseX] = 1; + } + if (Mouse::isButtonPressed(Mouse::Right)) { + int mouseX = Mouse::getPosition(win).x / ZOOM, mouseY = Mouse::getPosition(win).y / ZOOM; + if (!(mouseX < 0 + || mouseX > (int)board[0].size() + || mouseY < 0 + || mouseY > (int)board.size()) + ) board[mouseY][mouseX] = 0; + } + + win.setFramerateLimit(fps); + + win.display(); + win.clear(Color::Black); + } + + return 0; +} + +int countNeighbors (int x, int y, vector>* board) { + int count = 0; + for (int i = -1; i <= 1; i ++) { + for (int j = -1; j <= 1; j ++) { + if (i == 0 && j == 0) continue; + if ( + x + i <= 0 || + x + i >= (int)(*board)[0].size() || + y + j <= 0 || + y + j >= (int)(*board).size() + ) continue; + if ((*board)[y + j][x + i] == 1) count ++; + } + } + return count; +} + +bool willItSurvive (vector survive, int neighborCount) { + for (int i = 0; i < (int)survive.size(); i ++) { + if (neighborCount == survive[i]) return true; + } + return false; +} + +bool willItBeBorn (vector birth, int neighborCount) { + for (int i = 0; i < (int)birth.size(); i ++) { + if (neighborCount == birth[i]) return true; + } + return false; +} + +void check (int width, int height, vector* willBeBorn, vector* willBeDead, vector>* board) { + for (int i = 0; i < height; i ++) { + for (int j = 0; j < width; j ++) { + int neighborCount = countNeighbors(j, i, board); + if ((*board)[i][j] == 1) { + if (!willItSurvive({2,3}, neighborCount)) { + (*willBeDead).push_back({.x = j, .y = i}); + } + } else if ((*board)[i][j] == 0) { + if (willItBeBorn({3}, neighborCount)) { + (*willBeBorn).push_back({.x = j, .y = i}); + } + } + } + } +} + +void render (vector>* board, RenderWindow* win) { + for (int i = 0; i < (int)(*board).size(); i ++) { + for (int j = 0; j < (int)(*board)[0].size(); j ++) { + if ((*board)[i][j] == 1) { + RectangleShape* rectangle = new RectangleShape(Vector2f(j * ZOOM, i * ZOOM)); + rectangle->setPosition(Vector2f(j * ZOOM, i * ZOOM)); + rectangle->setSize(Vector2f(ZOOM, ZOOM)); + rectangle->setFillColor(Color::White); + win->draw(*rectangle); + delete rectangle; + } + } + } +} + +void nextStep (vector* willBeBorn, vector* willBeDead, vector>* board) { + for (int i = 0; i < (int)(*willBeBorn).size(); i ++) + (*board)[(*willBeBorn)[i].y][(*willBeBorn)[i].x] = 1; + willBeBorn->clear(); + + for (int i = 0; i < (int)(*willBeDead).size(); i ++) + (*board)[(*willBeDead)[i].y][(*willBeDead)[i].x] = 0; + willBeDead->clear(); +} \ No newline at end of file