diff options
author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2018-09-12 15:11:59 -0300 |
---|---|---|
committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2018-09-12 15:11:59 -0300 |
commit | e7307d06c5c90d9a02ba2d9c107491347983c14e (patch) | |
tree | 6a890cc10663caf4d5bd437eb6bef46dc8409bbb | |
download | life-e7307d06c5c90d9a02ba2d9c107491347983c14e.tar.gz life-e7307d06c5c90d9a02ba2d9c107491347983c14e.zip |
initial commit
-rwxr-xr-x | life.c | 142 | ||||
-rwxr-xr-x | readme.md | 27 |
2 files changed, 169 insertions, 0 deletions
@@ -0,0 +1,142 @@ +#define SDL_DISABLE_IMMINTRIN_H +#include <stdlib.h> +#include <time.h> +#include "SDL2/SDL.h" + +#define HEIGHT 80 +#define WIDTH 130 +#define SPF 1000 / 30 + +void wrap(int *a, int w) { + if (*a < 0) *a = w - 1; + else if (*a > w - 1) *a = 0; +} + +int place(int x, int y) { + wrap(&x, WIDTH); + wrap(&y, HEIGHT); + return x + y * WIDTH; +} + +int neighbors(char *cells, 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; + if (cells[place(i + x, j + y)] & 2) count++; + } + return count; +} + +int resize(SDL_Renderer *r) { + int w, h; + SDL_GetRendererOutputSize(r, &w, &h); + return w / WIDTH < h / HEIGHT ? w / WIDTH : h / HEIGHT; +} + +char inside(int n, char *v) { + char result = 0; + if (n >= 0 && n <= 8) + for (int i = 0; i < strlen(v); i++) { + result |= (n == v[i] - 48); + } + return result; +} + +void init(char *cells, char random) { + for (int x = 0; x < WIDTH; x++) { + for (int y = 0; y < HEIGHT; y++) { + if (random) cells[place(x, y)] ^= 3 * (rand() % 2); + else cells[place(x, y)] = 0; + } + } +} + +int main(int argc, char **argv) { + if (argc != 3) exit(1); + srand(time(0)); + SDL_Init(SDL_INIT_VIDEO); + SDL_Window *w = SDL_CreateWindow(argv[0], 0, 0, 800, 600, SDL_WINDOW_RESIZABLE); + SDL_Renderer *r = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED); + int cellsize = resize(r); + int oldtime = 0; + int newtime = 0; + char paused = 0; + char grid = 1; + int symtime = 0; + int rendertime = 0; + char cells[WIDTH * HEIGHT]; + init(cells, 1); + SDL_Event e; + while (e.type != SDL_QUIT) { + SDL_Delay(SPF); + while (SDL_PollEvent(&e)) { + if (e.window.event == SDL_WINDOWEVENT_RESIZED) + cellsize = resize(r); + if (e.key.state == SDL_PRESSED) { + if (e.key.keysym.sym == SDLK_BACKSPACE) + init(cells, 0); + if (e.key.keysym.sym == SDLK_RETURN) + init(cells, 1); + if (e.key.keysym.sym == SDLK_SPACE) + paused ^= 1; + if (e.key.keysym.sym == SDLK_PERIOD) { + paused = 1; + symtime = SPF + 1; + } + if (e.key.keysym.sym == SDLK_g) { + grid ^= 1; + } + } + int mx, my; + int mstate = SDL_GetMouseState(&mx, &my); + if (mstate & SDL_BUTTON(SDL_BUTTON_RIGHT)) { + cells[place(mx / cellsize, my / cellsize)] = 0; + paused = 1; + } else if (mstate & SDL_BUTTON(SDL_BUTTON_LEFT)) { + cells[place(mx / cellsize, my / cellsize)] = 3; + paused = 1; + } + }; + oldtime = newtime; + newtime = SDL_GetTicks(); + if (!paused) symtime += newtime - oldtime; + if (symtime > SPF) { + symtime = 0; + for (int x = 0; x < WIDTH; x++) + for (int y = 0; y < HEIGHT; y++) { + int n = neighbors(cells, x, y); + if (inside(n, argv[1]) && ~cells[place(x, y)] & 2) + cells[place(x, y)] |= 1; // Birth + if (!inside(n, argv[2]) && cells[place(x, y)] & 2) + cells[place(x, y)] &= 2; // Death + } + for (int i = 0; i < WIDTH * HEIGHT; i++) + cells[i] = cells[i] & 1 ? 3 : 0; + } + rendertime += newtime - oldtime; + if (rendertime > SPF) { + rendertime = 0; + SDL_SetRenderDrawColor(r, 160, 160, 160, 255); + SDL_RenderClear(r); + for (int x = 0; x < WIDTH; x++) + for (int y = 0; y < HEIGHT; y++) { + SDL_Rect rect = { x * cellsize, y * cellsize, cellsize, cellsize }; + if (grid && cellsize > 1) { + rect.x += 1; + rect.y += 1; + rect.w -= 1; + rect.h -= 1; + } + if (cells[place(x, y)]) SDL_SetRenderDrawColor(r, 0, 0, 0, 255); + else SDL_SetRenderDrawColor(r, 255, 255, 255, 255); + SDL_RenderFillRect(r, &rect); + } + SDL_RenderPresent(r); + } + } + SDL_DestroyRenderer(r); + SDL_DestroyWindow(w); + SDL_Quit(); + return 0; +} diff --git a/readme.md b/readme.md new file mode 100755 index 0000000..f251d95 --- /dev/null +++ b/readme.md @@ -0,0 +1,27 @@ +Compilation: gcc -o life -lSDL2 life.c + +Usage: life B S + + B neighbors needed to be born + + S neighbors needed to stay alive + +Example: life 3 23 + + Each cell becomes alive if it has 3 neighbors and stays alive if it has 2 or 3 neighbors. + +Keybindings: + + enter restart with random seed + + backspace clear screen + + space pause + + period step + + g toggle grid + + left mouse button draw + + right mouse button erase |