summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmma Doth <emmadoth@disroot.org>2023-05-08 23:26:37 +0200
committerEmma Doth <emmadoth@disroot.org>2023-05-08 23:26:37 +0200
commitc1a7f4c5384613efe17a356719112bcb1234e1a4 (patch)
treea8b8f0435874031927fc60466a9b3ace5bfe8eb1
parente904cd26f08238c893a0f9a07be3284a331fd142 (diff)
initial commit
-rw-r--r--.gitignore1
-rw-r--r--Makefile10
-rw-r--r--main.c109
3 files changed, 120 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e09ae52
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+cgol
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..55e8df9
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,10 @@
+WARN = -Wall -Wextra -Wconversion -Wvla
+
+default:
+ $(CC) $(WARN) main.c -o cgol
+
+debug:
+ $(CC) $(WARN) -g3 main.c -o cgol
+
+run: default
+ ./cgol
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..a81abe6
--- /dev/null
+++ b/main.c
@@ -0,0 +1,109 @@
+#include <stdio.h>
+
+#define WIDTH 213
+#define HEIGHT 56
+
+#define F_ARGS _Bool board[HEIGHT][WIDTH], int neighbours[HEIGHT][WIDTH], int y, int x
+
+int get_neighbours(_Bool board[HEIGHT][WIDTH], int y, int x)
+{
+ int neighbours = 0;
+
+ if(y > 0)
+ {
+ if(board[y - 1][x]) ++neighbours; // n
+
+ if((x + 1) < WIDTH && board[y - 1][x + 1]) ++neighbours; // ne
+ if( x > 0 && board[y - 1][x - 1]) ++neighbours; // nw
+ }
+
+ if((x + 1) < WIDTH && board[y][x + 1]) ++neighbours; // e
+ if( x > 0 && board[y][x - 1]) ++neighbours; // w
+
+ if((y + 1) < HEIGHT)
+ {
+ if(board[y + 1][x]) ++neighbours; // s
+
+ if((x + 1) < WIDTH && board[y + 1][x + 1]) ++neighbours; // se
+ if( x > 0 && board[y + 1][x - 1]) ++neighbours; // sw
+ }
+
+ return neighbours;
+}
+
+void iter(void (*f)(F_ARGS), _Bool board[HEIGHT][WIDTH], int neighbours[HEIGHT][WIDTH])
+{
+ for(int y = 0; y < HEIGHT; ++y)
+ {
+ for(int x = 0; x < WIDTH; ++x)
+ {
+ (*f)(board, neighbours, y, x);
+ }
+ }
+}
+
+void print_board_pos(F_ARGS)
+{
+ board[y][x] ? putc('*', stdout) : putc('.', stdout);
+ if(x + 1 == WIDTH)
+ putc('\n', stdout);
+}
+
+void calculate_neighbours(F_ARGS)
+{
+ neighbours[y][x] = get_neighbours(board, y, x);
+}
+
+void apply_rules(F_ARGS)
+{
+ if(neighbours[y][x] < 2 || neighbours[y][x] > 3)
+ {
+ board[y][x] = 0;
+ }
+ else if(neighbours[y][x] == 3)
+ {
+ board[y][x] = 1;
+ }
+}
+
+int handle_input(int input)
+{
+ switch(input)
+ {
+ case 'q':
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+int main(void)
+{
+ _Bool board[HEIGHT][WIDTH] = { 0 };
+ int neighbours[HEIGHT][WIDTH] = { 0 };
+
+ board[0][1] = 1;
+ board[1][2] = 1;
+ board[2][0] = 1;
+ board[2][1] = 1;
+ board[2][2] = 1;
+
+ iter(&print_board_pos, board, neighbours);
+
+ int input = getchar();
+ _Bool run = handle_input(input);
+
+ while(run)
+ {
+ iter(&calculate_neighbours, board, neighbours);
+
+ iter(&apply_rules, board, neighbours);
+
+ iter(&print_board_pos, board, neighbours);
+
+ input = getchar();
+ run = handle_input(input);
+ }
+
+ return 0;
+}