From e7307d06c5c90d9a02ba2d9c107491347983c14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Wed, 12 Sep 2018 15:11:59 -0300 Subject: initial commit --- life.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100755 life.c (limited to 'life.c') diff --git a/life.c b/life.c new file mode 100755 index 0000000..de8e1b8 --- /dev/null +++ b/life.c @@ -0,0 +1,142 @@ +#define SDL_DISABLE_IMMINTRIN_H +#include +#include +#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; +} -- cgit v1.2.3