gol

Implementation of Conway's Game of Life writen in C
git clone git://git.dimitrijedobrota.com/gol.git
Log | Files | Refs | README

commit 4215fc765b6900a1c8f7f579609f6a667f1b39ec
parent f22cebbbe089efb4e7b627e2d7bd5acf5409e2df
Author: Mateja Marsenic <matejamarsenic@gmail.com>
Date:   Sat, 21 May 2022 20:28:26 +0200

Added All Mods(Some still not working)

Diffstat:
M.gitignore | 2+-
Asrc/logic.c | 254+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 255 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore @@ -1,7 +1,7 @@ .ccls-cache/ .ccls .clang-format - +.vscode/ bin/* !bin/dir.info diff --git a/src/logic.c b/src/logic.c @@ -0,0 +1,253 @@ +#include <stdio.h> +#include <stdlib.h> + +#define MAX(a, b) ((a > b) ? a : b) +#define MIN(a, b) ((a < b) ? a : b) + +#define t mat[i][j] +#define u_char unsigned char +// GLOBALS + +u_char **mat; +int h, w; +u_char mod; + +void addToECells(a, b) { + mod = (mat[a][b] & 3); + switch (mod) { + case 1: + mod = mod << 2; + break; + case 2: + mod = mod << 4; + break; + default: + return; + } + + for (int i = MAX(a - 1, 0); i <= MIN(a + 1, h); i++) + for (int j = MAX(b - 1, 0); j <= MIN(b + 1, w + 1); j++) + if (i != a || j != b) + mat[i][j] += mod; +} +void addToCells(i, j) { + mod = (mat[i][j] & 3); + switch (mod) { + case 1: + mod = mod << 2; + break; + case 2: + mod = mod << 4; + break; + default: + return; + } + for (int k = i - 1; k <= i + 1; k++) + for (int l = j - 1; l <= j + 1; l++) + if (k != i || l != j) + mat[k][l] += mod; +} +void doAdditions(void) { + for (int j = 1; j <= w; j++) { + mat[0][j] = mat[h][j]; + mat[h + 1][j] = mat[1][j]; + addToECells(0, j); + addToECells(h + 1, j); + } + + for (int i = 1; i < h; i++) { + mat[i][0] = mat[i][w]; + mat[i][w + 1] = mat[i][1]; + addToECells(i, 0); + addToECells(i, w + 1); + } + + mat[0][0] = mat[h][w]; + mat[0][w + 1] = mat[h][1]; + mat[h + 1][0] = mat[1][w]; + mat[h + 1][w + 1] = mat[1][1]; + + addToECells(0, 0); + addToECells(0, w + 1); + addToECells(h + 1, 0); + addToECells(h + 1, w + 1); + + /* Normal AddToCells */ + for (int i = 1; i <= h; i++) + for (int j = 1; j <= w; j++) + addToCells(i, j); +} + +void evolveNormal(void) { + doAdditions(); + /* Rules */ + for (int i = 1; i <= h; i++) + for (int j = 1; j <= w; j++) + switch (mat[i][j]) { + case 9: + case 12: + case 13: + mat[i][j] = 1; + break; + default: + mat[i][j] = 0; + } +} + +void evolveCoExist(void) { + unsigned char s1, s2; + doAdditions(); + for (int i = 1; i <= h; i++) { + for (int j = 1; j <= w; j++) { + s2 = mat[i][j] >> 5; + s1 = (mat[i][j] & 31) >> 2; + if ((mat[i][j] & 3) == 0) { + if ((s1 + s2) == 3) { + if (mat[i][j] >= 64) + mat[i][j] = 2; + else + mat[i][j] = 1; + } + } else { + if ((s1 + s2) < 2 || (s1 + s2) > 3) { + mat[i][j] = 0; + } + } + } + } +} + +void evolvePredator(void) { + unsigned char s1, s2; + doAdditions(); + for (int i = 1; i <= h; i++) { + for (int j = 1; j <= w; j++) { + s2 = mat[i][j] >> 5; + s1 = (mat[i][j] & 31) >> 2; + mod = mat[i][j] & 3; + if ((s1 + s2) < 2 || (s1 + s2) > 3) { + mat[i][j] = 0; + continue; + } + switch (mod) { + case 0: + if ((s1 + s2) == 3) { + if (mat[i][j] >= 64) + mat[i][j] = 2; + else + mat[i][j] = 1; + } + break; + case 1: + if (s2 > 0) + mat[i][j] = 0; + break; + } + } + } +} + +void evolveVirus(void) { + unsigned char s1, s2; + doAdditions(); + for (int i = 1; i <= h; i++) { + for (int j = 1; j <= w; j++) { + s2 = mat[i][j] >> 5; + s1 = (mat[i][j] & 31) >> 2; + mod = mat[i][j] & 3; + if ((s1 + s2) < 2 || (s1 + s2) > 3) { + mat[i][j] = 0; + continue; + } + switch (mod) { + case 0: + if ((s1 + s2) == 3) { + if (mat[i][j] >= 64) + mat[i][j] = 2; + else + mat[i][j] = 1; + } + break; + case 1: + if (s2 > 0) + mat[i][j] = 2; + break; + } + } + } +} + +void evolveUnknown(void) { // NE RADI + unsigned char s1, s2; + doAdditions(); + for (int i = 1; i <= h; i++) { + for (int j = 1; j <= w; j++) { + s2 = mat[i][j] >> 5; + s1 = (mat[i][j] & 31) >> 2; + if ((mat[i][j] & 3) == 0) { + if ((s1 == 3 || s2 == 3) && (s1 + s2) == 3) { + if (mat[i][j] >= 96) + mat[i][j] = 2; + else + mat[i][j] = 1; + } + } else { + if ((s1 + s2) < 2 || (s1 + s2) > 3) { + mat[i][j] = 0; + } + } + } + } +} + +void do_evolution(int steps, void (*evolution)(void)) { + while (steps--) { + evolution(); + print_matrix(); + usleep(500000); + } +} + +void print_matrix(void) { + printf("\n"); + for (int i = 1; i <= h; i++) { + for (int j = 1; j <= w; j++) { + printf("%d ", mat[i][j] & 3); + } + printf("\n"); + } +} + +int main(void) { + int mode; + + srand(time(NULL)); + printf("Enter Size (W H): "); + scanf("%d %d", &h, &w); + + mat = malloc((h + 2) * sizeof(u_char *)); + for (int i = 0; i <= h + 1; i++) + mat[i] = calloc((w + 2), sizeof(u_char)); + + printf("Enter Matrix:\n"); + for (int i = 1; i <= h; i++) + for (int j = 1; j <= w; j++) { + scanf("%d", &mat[i][j]); + } + + int steps = 3; + void (*evolution_modes[])() = {evolveNormal, evolveCoExist, evolvePredator, + evolveVirus, evolveUnknown}; + + print_matrix(); + printf("\nEnter Mode: "); + scanf("%d", &mode); + + do_evolution(steps, evolution_modes[mode]); + + for (int i = 0; i <= h + 1; i++) + free(mat[i]); + free(mat); + + return 0; +} +\ No newline at end of file