diff options
| author | Bobby <[email protected]> | 2023-09-11 23:22:50 -0400 |
|---|---|---|
| committer | Bobby <[email protected]> | 2023-09-11 23:22:50 -0400 |
| commit | 2876b8b38f699b3062230a7b570b45cc7399716e (patch) | |
| tree | 16044732c690de0b92cdbd1f91135825b3f5c299 /src | |
| download | gameoflife-2876b8b38f699b3062230a7b570b45cc7399716e.tar.xz gameoflife-2876b8b38f699b3062230a7b570b45cc7399716e.zip | |
Added Game of Life
Diffstat (limited to 'src')
| -rw-r--r-- | src/constants.h | 3 | ||||
| -rw-r--r-- | src/game.h | 47 | ||||
| -rw-r--r-- | src/gameOfLife.cpp | 40 | ||||
| -rw-r--r-- | src/screen.h | 62 |
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; + } + } + } +}; |
