commit f4f5874b51817bdae4ac9d1d23aeec6f48be8fea
parent 34456a0a2000198ad2141165609dc0fb9b1e0918
Author: aabacchus <ben@bvnf.space>
Date: Mon, 27 Sep 2021 05:52:09 +0100
add rules, __TEST cases
Diffstat:
M | cgol.h | | | 9 | +++++++++ |
M | main.c | | | 68 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
A | rules.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;
+}