cgol

a cairo-based Game Of Life
Log | Files | Refs

commit f4f5874b51817bdae4ac9d1d23aeec6f48be8fea
parent 34456a0a2000198ad2141165609dc0fb9b1e0918
Author: aabacchus <ben@bvnf.space>
Date:   Mon, 27 Sep 2021 05:52:09 +0100

add rules, __TEST cases

Diffstat:
Mcgol.h | 9+++++++++
Mmain.c | 68+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Arules.c | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 174 insertions(+), 5 deletions(-)

diff --git a/cgol.h b/cgol.h @@ -15,6 +15,8 @@ #include <cairo.h> #include <stdio.h> +#include <stdlib.h> +#include <time.h> struct rgb { double r, g, b; @@ -26,5 +28,12 @@ struct imgdata { struct rgb a, i, b; /* RGB for active, inactive, background pixels */ }; +int alive(int x, int y, short *cells, int nx, int ny); +int evolve(short *cells, int nx, int ny); +int neighbours(int x, int y, short *cells, int nx, int ny); +#ifdef __TEST +int verbose_neighbours(int x, int y, short *cells, int nx, int ny); +#endif /* cells[i][j] should match i = img->ny, j = img->nx */ int png(struct imgdata *img, short *cells, char *fname); +void randomize(short *cells, int nx, int ny); diff --git a/main.c b/main.c @@ -3,17 +3,75 @@ */ #include "cgol.h" +#ifndef __TEST +#define NROWS 20 +#define NCOLS 20 +#else +#define NROWS 10 +#define NCOLS 10 +#endif + int main(void) { + int n_gens = 200; struct imgdata img = { - 200, 200, - 11, 10, + 400, 400, + NROWS, NCOLS, { 1, 1, 1, }, { 0.1, 0.1, 0.1 }, { 0, 0, 0 } }; - short cells[11][10] = { 0 }; - if (png(&img, &cells[0][0], "out.png") != 0) - return 1; +#ifndef __TEST + short cells[NROWS][NCOLS] = { 0 }; + + randomize(&cells[0][0], NCOLS, NROWS); +#else + short cells[NROWS][NCOLS] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + + int x, y; + x = 1; + y = 2; + printf("%d,%d = %hd and has %d neighbours\n", x, y, cells[y][x], neighbours(x, y, &cells[0][0], NCOLS, NROWS)); +#endif + + int gen, n_alive; + char *fn = malloc(12 + 4); + for (gen = 0; gen < n_gens; gen++) { +#ifdef __TEST + printf("==> GEN %d <==\n", gen); +#endif + sprintf(fn, "images/%04d.png", gen); + if (png(&img, &cells[0][0], fn) != 0) { + free(fn); + return 1; + } + n_alive = evolve(&cells[0][0], NCOLS, NROWS); +#ifndef __TEST + printf("%d\n", n_alive); +#endif + } + free(fn); + return 0; + +} + +void +randomize(short *cells, int nx, int ny) { + srand(time(NULL)); + int i, j; + for (i = 0; i < ny; i++) + for (j = 0; j < nx; j++) + *(cells + i * nx + j) = rand() % 2 ? 1 : 0; } diff --git a/rules.c b/rules.c @@ -0,0 +1,102 @@ +#include "cgol.h" + +#define WHATS_OUTSIDE 0 + +int +evolve(short *cells, int nx, int ny) { + int i, j; + int n_alive; + short newcells[ny][nx]; + n_alive = 0; + for (i = 0; i < ny; i++) { + for (j = 0; j < nx; j++) { + int n = neighbours(j, i, cells, nx, ny); + int isalive = alive(j, i, cells, nx, ny); +#ifdef __TEST + if (n) { + printf("%d,%d is %d and has %d neighbours\n", j, i, isalive, n); + verbose_neighbours(j, i, cells, nx, ny); + } +#endif + if (isalive && (n == 2 || n == 3)) { + newcells[i][j] = 1; + n_alive++; + continue; + } else if (!isalive && n == 3) { + newcells[i][j] = 1; + n_alive++; + } else { + newcells[i][j] = 0; + } + } + } + + for (i = 0; i < ny; i++) + for (j = 0; j < nx; j++) + *(cells + i * nx + j) = newcells[i][j]; + + return n_alive; +} + +int +alive(int x, int y, short *cells, int nx, int ny) { + if (y < 0 || y >= ny || x < 0 || x >= nx) + return WHATS_OUTSIDE; + return (int) *(cells + y * nx + x); +} + +int +neighbours(int x, int y, short *cells, int nx, int ny) { + int n = 0; + int x0, y0; + for (y0 = y - 1; y0 <= y + 1; y0++) { + /* + if (y0 < 0 || y0 >= ny) { + n += WHATS_OUTSIDE; + continue; + } + */ + for (x0 = x - 1; x0 <= x + 1; x0++) { + /* + if (x0 < 0 || x0 >= nx) { + n += WHATS_OUTSIDE; + continue; + } + */ + if (alive(x0, y0, cells, nx, ny)) + n++; + } + } + if (alive(x, y, cells, nx, ny)) + n--; + + return n; +} + +int +verbose_neighbours(int x, int y, short *cells, int nx, int ny) { + int n = 0; + int x0, y0; + for (y0 = y - 1; y0 <= y + 1; y0++) { + if (y0 < 0 || y0 >= ny) { + n += WHATS_OUTSIDE; + continue; + } + for (x0 = x - 1; x0 <= x + 1; x0++) { + if (x0 < 0 || x0 >= nx) { + n += WHATS_OUTSIDE; + continue; + } + if (alive(x0, y0, cells, nx, ny)) { + printf("%d,%d: %d,%d found\n", x, y, x0, y0); + n++; + } + } + } + if (alive(x, y, cells, nx, ny)) + n--; + + printf("found %d neighbours\n", n); + + return n; +}