aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBobby <[email protected]>2023-09-11 23:22:50 -0400
committerBobby <[email protected]>2023-09-11 23:22:50 -0400
commit2876b8b38f699b3062230a7b570b45cc7399716e (patch)
tree16044732c690de0b92cdbd1f91135825b3f5c299 /src
downloadgameoflife-2876b8b38f699b3062230a7b570b45cc7399716e.tar.xz
gameoflife-2876b8b38f699b3062230a7b570b45cc7399716e.zip
Added Game of Life
Diffstat (limited to 'src')
-rw-r--r--src/constants.h3
-rw-r--r--src/game.h47
-rw-r--r--src/gameOfLife.cpp40
-rw-r--r--src/screen.h62
4 files changed, 152 insertions, 0 deletions
diff --git a/src/constants.h b/src/constants.h
new file mode 100644
index 0000000..bb73900
--- /dev/null
+++ b/src/constants.h
@@ -0,0 +1,3 @@
+const int SCREEN_WIDTH = 640;
+const int SCREEN_HEIGHT = 480;
+const int SCALE_FACTOR = 2; \ No newline at end of file
diff --git a/src/game.h b/src/game.h
new file mode 100644
index 0000000..5f14541
--- /dev/null
+++ b/src/game.h
@@ -0,0 +1,47 @@
+#include <array>
+#include <random>
+#include "screen.h"
+
+using Array2D = std::array<std::array<int, SCREEN_HEIGHT>, SCREEN_WIDTH>;
+
+// Two-dimensional array of ints
+struct Game {
+ Array2D display {};
+ Array2D swap {};
+};
+
+// random number generator function:
+int zeroOrOne() {
+ std::random_device rd;
+ std::mt19937 gen(rd());
+ std::uniform_int_distribution<> dis(0, 1);
+ return dis(gen);
+}
+
+// function to check if the cell will be alive or dead in the next generation
+bool isAlive(Array2D &game, int x, int y) {
+ int alive = 0;
+
+ // left test
+ if (x > 0 && game[x - 1][y] == 1) alive++;
+ // right test
+ if (x < SCREEN_WIDTH && game[x + 1][y] == 1) alive++;
+ // top test
+ if (y > 0 && game[x][y - 1] == 1) alive++;
+ // bottom test
+ if (y < SCREEN_HEIGHT && game[x][y + 1] == 1) alive++;
+ // top left test
+ if (x > 0 && y > 0 && game[x - 1][y - 1] == 1) alive++;
+ // top right test
+ if (x < SCREEN_WIDTH && y > 0 && game[x + 1][y - 1] == 1) alive++;
+ // bottom left test
+ if (x > 0 && y < SCREEN_HEIGHT && game[x - 1][y + 1] == 1) alive++;
+ // bottom right test
+ if (x < SCREEN_WIDTH && y < SCREEN_HEIGHT && game[x + 1][y + 1] == 1) alive++;
+
+ // if the cell is alive and has 2 or 3 neighbors, it stays alive or
+ // if the cell is dead and has exactly 3 neighbors, it comes to life
+ if ((game[x][y] == 1 && (alive == 2 || alive == 3)) || (game[x][y] == 0 && alive == 3)) return true;
+ // otherwise, the cell dies
+ else return false;
+}
diff --git a/src/gameOfLife.cpp b/src/gameOfLife.cpp
new file mode 100644
index 0000000..976d4ae
--- /dev/null
+++ b/src/gameOfLife.cpp
@@ -0,0 +1,40 @@
+#include "game.h"
+
+int main() {
+ Game game;
+ GameScreen screen;
+
+ // create random points
+ for (auto &row : game.display) {
+ std::generate(row.begin(), row.end(), zeroOrOne);
+ }
+
+ // game loop
+ for(;;) {
+ // check for alive cells
+ for (int i = 0; i < SCREEN_WIDTH; ++i) {
+ for (int j = 0; j < SCREEN_HEIGHT; ++j) {
+ // check if the cell will be alive or dead in the next generation
+ game.swap[i][j] = isAlive(game.display, i, j) ? 1 : 0;
+ }
+ }
+
+ // draw
+ for (int i = 0; i < SCREEN_WIDTH; ++i) {
+ for (int j = 0; j < SCREEN_HEIGHT; ++j) {
+ if (game.swap[i][j] == 1) {
+ screen.drawPixel(i, j);
+ }
+ }
+ }
+
+ // swap buffers
+ std::copy(game.swap.begin(), game.swap.end(), game.display.begin());
+
+ // display to screen
+ screen.update();
+ SDL_Delay(20);
+ screen.input();
+ screen.clearPixels();
+ }
+}
diff --git a/src/screen.h b/src/screen.h
new file mode 100644
index 0000000..9aa242d
--- /dev/null
+++ b/src/screen.h
@@ -0,0 +1,62 @@
+#include <SDL2/SDL.h>
+#include <cstdlib>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include "constants.h"
+
+// Game Screen Class -> Uses SDL2
+class GameScreen {
+ SDL_Window *window{};
+ SDL_Renderer *renderer{};
+ SDL_bool done;
+ std::vector<SDL_FPoint> points;
+ std::vector<SDL_Color> colors;
+ SDL_Event event{};
+
+public:
+ GameScreen() {
+ SDL_Init(SDL_INIT_VIDEO);
+ SDL_CreateWindowAndRenderer(SCREEN_WIDTH * SCALE_FACTOR,
+ SCREEN_HEIGHT * SCALE_FACTOR,
+ 0, &window, &renderer);
+ SDL_SetWindowTitle(window, "Game of Life");
+ SDL_RenderSetScale(renderer, SCALE_FACTOR, SCALE_FACTOR);
+ done = SDL_FALSE;
+ }
+
+ void drawPixel(double xm, double ym, uint8_t r = 255, uint8_t g = 255, uint8_t b = 255, uint8_t a = 255) {
+ points.push_back({static_cast<float>(xm), static_cast<float>(ym)});
+ colors.push_back({r, g, b, a});
+ }
+
+ void clearPixels() {
+ points.clear();
+ }
+
+ void update() {
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+ SDL_RenderClear(renderer);
+
+ for (long unsigned int i = 0; i < points.size(); ++i) {
+ SDL_SetRenderDrawColor(renderer, colors[i].r, colors[i].g, colors[i].b, colors[i].a);
+ SDL_RenderDrawPointF(renderer, points[i].x, points[i].y);
+ }
+
+ SDL_RenderPresent(renderer);
+ }
+
+ void input() {
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_QUIT:
+ done = SDL_TRUE;
+ SDL_Quit();
+ exit(0);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+};