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 |
#include <SFML/Graphics.hpp> #include <vector> using namespace std; using namespace sf; // Function to update the grid based on the Game of Life rules void updateGrid(vector<vector<bool>>& grid) { int rows = grid.size(); int cols = grid[0].size(); vector<vector<bool>> newGrid(rows, vector<bool>(cols, false)); // Helper function to count live neighbors auto countLiveNeighbors = [&](int x, int y) { int count = 0; for (int i = -1; i <= 1; ++i) { for (int j = -1; j <= 1; ++j) { if (i == 0 && j == 0) continue; int ni = x + i, nj = y + j; if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && grid[ni][nj]) { ++count; } } } return count; }; // Update each cell based on its neighbors for (int x = 0; x < rows; ++x) { for (int y = 0; y < cols; ++y) { int liveNeighbors = countLiveNeighbors(x, y); if (grid[x][y]) { newGrid[x][y] = (liveNeighbors == 2 || liveNeighbors == 3); } else { newGrid[x][y] = (liveNeighbors == 3); } } } grid = newGrid; } // Main function int main() { const int cellSize = 10; const int width = 80; const int height = 60; const int windowWidth = width * cellSize; const int windowHeight = height * cellSize; // Create the window RenderWindow window(VideoMode(windowWidth, windowHeight), "Game of Life"); // Initialize grid vector<vector<bool>> grid(height, vector<bool>(width, false)); // Set initial pattern (glider) grid[10][10] = true; grid[10][11] = true; grid[10][12] = true; grid[11][12] = true; grid[12][11] = true; Clock clock; float elapsed = 0; float interval = 0.1f; // Update interval in seconds while (window.isOpen()) { // Event handling Event event; while (window.pollEvent(event)) { if (event.type == Event::Closed) window.close(); } // Update the grid at regular intervals elapsed += clock.restart().asSeconds(); if (elapsed >= interval) { elapsed = 0; updateGrid(grid); } // Clear the window window.clear(Color::White); // Draw the grid for (int x = 0; x < height; ++x) { for (int y = 0; y < width; ++y) { RectangleShape cell(Vector2f(cellSize, cellSize)); cell.setPosition(y * cellSize, x * cellSize); cell.setFillColor(grid[x][y] ? Color::Black : Color::White); window.draw(cell); } } // Display the updated window window.display(); } return 0; } |
Explanation:
- Game of Life Rules (
updateGrid
):- The
updateGrid
function updates the grid according to Conway’s Game of Life rules:- A live cell with 2 or 3 live neighbors remains alive; otherwise, it dies.
- A dead cell with exactly 3 live neighbors becomes alive.
- The
- Neighbor Counting (
countLiveNeighbors
):- A lambda function counts the number of live neighbors for a given cell. It iterates over adjacent cells, excluding the cell itself.
- Main Function (
main
):- Initializes an SFML window with a specific size.
- Creates a grid of cells and sets an initial pattern (a glider in this case).
- Uses a
Clock
to control the update interval of the grid. - Handles events and updates the grid at regular intervals.
- Clears the window, draws the grid cells, and displays the result.
- SFML Graphics:
- The
RectangleShape
class is used to draw each cell in the grid. Cells are drawn as black or white rectangles depending on their state (alive or dead).
- The
Possible Enhancements:
- User Interaction: Allow users to interact with the grid to set initial states or pause/resume the simulation.
- Different Patterns: Implement different initial patterns or load patterns from files.
- Performance Optimization: Optimize the rendering and updating process for larger grids.
- GUI Controls: Add buttons and sliders for controlling the simulation speed and other parameters.