#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(); }