]> git.huck.website - gol.git/commitdiff
resizable unicode
authorHuck Boles <huck@huck.website>
Sun, 22 Jan 2023 19:02:01 +0000 (13:02 -0600)
committerHuck Boles <huck@huck.website>
Sun, 22 Jan 2023 19:02:01 +0000 (13:02 -0600)
.gitignore
src/function.c [new file with mode: 0644]
src/gol.c [new file with mode: 0644]
src/gol.h [new file with mode: 0644]
src/map.c [new file with mode: 0644]
src/struct.c [new file with mode: 0644]
test/errortest.c [new file with mode: 0644]
test/helptest.c [new file with mode: 0644]

index 291983fea527e70704c329941d8b21c33315f0c6..5a1b38fdcf8b141842255e400099439fc5e9a299 100644 (file)
@@ -3,5 +3,7 @@
 !README
 !LICENSE
 !Makefile
+!src/
+!test/
 !*.c
 !*.h
diff --git a/src/function.c b/src/function.c
new file mode 100644 (file)
index 0000000..8b867dd
--- /dev/null
@@ -0,0 +1,72 @@
+#include "gol.h"
+
+
+extern int row,col,step,ascii,color,weight;
+
+void parseopts(int n, char **args){
+    char c;
+    while ((c = getopt(n,args,"hVacy:x:t:w:")) != -1){
+        switch (c) {
+            case 'h':
+                help();
+                break;
+            case 'V':
+                printf("v%s\n",VERSION);
+                exit(0);
+                break;
+            case 'x':
+                col = strtol(optarg,NULL,10);
+                break;
+            case 'y':
+                row = strtol(optarg,NULL,10);
+                break;
+            case 't':
+                step = strtol(optarg,NULL,10);
+                break;
+            case 'w':
+                weight = strtol(optarg,NULL,10);
+                break;
+            case 'a':
+                ascii = 1;
+                break;
+            case '?':
+                fprintf(stderr, "\t%s\n",optarg);
+                errorcheck(FLAG_ERR);
+                break;
+        }
+    }
+
+    return;
+}
+
+void errorcheck(int err){
+    if (errno != 0) {
+        fprintf(stderr,"\nERROR: %s\n",strerror(errno));
+        exit(EXIT_FAILURE);
+    } 
+
+    if (err == NO_ERR) { return; }
+
+    if ((err & FLAG_ERR) != 0) {
+        fprintf(stderr,"ERROR: Unknown Flag\n");
+        printf("Use -h for help");
+    }
+
+    if ((err & STATE_ERR) != 0) { fprintf(stderr,"ERROR: Could not determine cell state\n"); }
+
+    exit(err);
+}
+
+void help(){
+    printf("Usage:\n");
+    printf("\tgol [OPTIONS]");
+    printf("Option flags:\n");
+    printf("\t-x [INT]\tnumber of columns, default: 90\n");
+    printf("\t-y [INT]\tnumber of rows, default: 30\n");
+    printf("\t-a \tascii only mode\n");
+    printf("\t-t [ms]\tamount of time to wait in ms between generations, default: 75000\n");
+    printf("\t-V\tversion information\n");
+    printf("\t-h\tshow this help\n");
+
+    exit(0);
+}
diff --git a/src/gol.c b/src/gol.c
new file mode 100644 (file)
index 0000000..093a368
--- /dev/null
+++ b/src/gol.c
@@ -0,0 +1,46 @@
+#include "gol.h"
+
+int  row,col,step,ascii,weight;
+
+int main(int argc, char *argv[]){
+    srand(time(NULL));
+
+    int stop = 1;
+    row = 30;
+    col = 90;
+    step = 75000;
+    ascii = 0;
+    weight = 5;
+
+    parseopts(argc,argv);
+
+    struct map map = newmap();
+    genmap(map);
+
+    while (stop > 0){
+        stop = updatemap(map);
+        printdisplay(map);
+        usleep(step);
+    }
+
+    freemap(map);
+
+    return 0;
+}
+
+
+void printdisplay(struct map map){
+    printf("%s",CLEAR);
+    for (int r = 0; r < row; r++){
+        for (int c = 0; c < col; c++){
+            if (ascii == 0){
+                printf("%4s",map.line[r].cell[c].pixel);
+            } else {
+                printf("%c",map.line[r].cell[c].cellchar);
+            }
+        }
+        putc('\n',stdout);
+    }
+
+    return;
+}
diff --git a/src/gol.h b/src/gol.h
new file mode 100644 (file)
index 0000000..517b808
--- /dev/null
+++ b/src/gol.h
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <error.h>
+#include <time.h>
+#include <wchar.h>
+
+#define MAXLINE 10000
+#define VERSION "0.2.1"
+
+#define CLEAR "\e[1;1H\e[2J"
+
+enum {DIE = -1, DEAD = 0, ALIVE = 1, SPAWN = 1 << 1};
+
+/* error codes */
+enum {NO_ERR = 0, FLAG_ERR = 1, STATE_ERR = 1 << 1, COLOR_ERR = 1 << 2};
+
+struct cell {
+    char    pixel[4];
+    char    cellchar;
+    int     state;
+};
+
+struct line {
+     struct cell *cell;
+};
+
+struct map {
+    struct line *line;
+};
+
+/* main.c */
+void errorcheck(int);
+void parseopts(int,char **);
+void help(void);
+void printdisplay(struct map);
+
+/* map.c */
+void genmap(struct map);
+int updatemap(struct map);
+int numneighbor(struct map,int,int);
+int checkstate(struct map,int,int);
+char statechar(int);
+char *statecell(int);
+
+/* struct.c */
+struct map newmap(void);
+void freemap(struct map);
diff --git a/src/map.c b/src/map.c
new file mode 100644 (file)
index 0000000..0e81cef
--- /dev/null
+++ b/src/map.c
@@ -0,0 +1,143 @@
+#include "gol.h"
+
+extern int row,col,weight;
+
+void genmap(struct map map){
+    int rnd = 0;
+    for (int r = 0; r < row; r++){
+        for (int c = 0; c < col; c++){
+            rnd = rand();
+            if (rnd % weight == 0){
+                map.line[r].cell[c].state = ALIVE;
+            } else {
+                map.line[r].cell[c].state = DEAD;
+            }
+        }
+    }
+    return;
+}
+
+int updatemap(struct map map){
+    int n = 0;
+    struct map tmp = newmap();
+
+    for (int r = 1; r < row-1; r++){
+        for(int c = 1; c < col-1; c++){
+            int state = checkstate(map,r,c);
+            tmp.line[r].cell[c].state = state;
+            tmp.line[r].cell[c].cellchar = statechar(state);
+            strncpy(tmp.line[r].cell[c].pixel,statecell(state),4);
+            if (state > DEAD){ n++; }
+        }
+    }
+
+    for(int r = 0; r < row; r++){
+        for (int c = 0; c < col; c++){
+            map.line[r].cell[c] = tmp.line[r].cell[c];
+        }
+    }
+
+    return n;
+}
+
+int checkstate(struct map map,int r, int c){
+    int state = 0;
+    int n = numneighbor(map, r, c);
+
+    if (map.line[r].cell[c].state < ALIVE) {
+        if (n == 3) {
+            state = SPAWN;
+        } else {
+            state = DEAD;
+        }
+    } else {
+        if (n > 1 && n < 4) {
+            state = ALIVE;
+        } else {
+            state = DIE;
+        }
+    }
+
+    return state;
+}
+
+char statechar(int state){
+    switch (state) {
+        case (DIE): return ' ';
+        case (SPAWN): return '#';
+        case (ALIVE): return '#';
+        case (DEAD): return ' ';
+        default:
+            errorcheck(STATE_ERR);
+            return 'E';
+    }
+}
+
+char *statecell(int state){
+    switch (state) {
+        case (DIE): return "\u25CC";
+        case (SPAWN): return "\u25CB";
+        case (ALIVE): return "\u25EF";
+        case (DEAD): return "\u2002";
+        default:
+            errorcheck(STATE_ERR);
+            return "X";
+    }
+}
+
+
+int numneighbor(struct map map, int r, int c){
+    int n = 0;
+    /* non-edges */
+    if (r > 0 && r < row - 1 && c > 0 && c < col - 1){
+        if (map.line[r+1].cell[c+1].state > DEAD) n ++;
+        if (map.line[r].cell[c+1].state > DEAD) n ++;
+        if (map.line[r-1].cell[c+1].state > DEAD) n ++;
+        if (map.line[r+1].cell[c].state > DEAD) n ++;
+        if (map.line[r-1].cell[c].state > DEAD) n ++;
+        if (map.line[r+1].cell[c-1].state > DEAD) n ++;
+        if (map.line[r].cell[c-1].state > DEAD) n ++;
+        if (map.line[r-1].cell[c-1].state > DEAD) n ++;
+    /* top row */
+    } else if (r == 0 && c > 0 && c < col){
+        if (map.line[r+1].cell[c+1].state > DEAD) n ++;
+        if (map.line[r].cell[c+1].state > DEAD) n ++;
+        if (map.line[row-1].cell[c+1].state > DEAD) n ++;
+        if (map.line[r+1].cell[c].state > DEAD) n ++;
+        if (map.line[row-1].cell[c].state > DEAD) n ++;
+        if (map.line[r+1].cell[c-1].state > DEAD) n ++;
+        if (map.line[r].cell[c-1].state > DEAD) n ++;
+        if (map.line[row-1].cell[c-1].state > DEAD) n ++;
+    /* bottom row */
+    } else if (r == row - 1 && c > 0 && c < col){
+        if (map.line[0].cell[c+1].state > DEAD) n ++;
+        if (map.line[r].cell[c+1].state > DEAD) n ++;
+        if (map.line[r-1].cell[c+1].state > DEAD) n ++;
+        if (map.line[0].cell[c].state > DEAD) n ++;
+        if (map.line[r-1].cell[c].state > DEAD) n ++;
+        if (map.line[0].cell[c-1].state > DEAD) n ++;
+        if (map.line[r].cell[c-1].state > DEAD) n ++;
+        if (map.line[r-1].cell[c-1].state > DEAD) n ++;
+    /* left side */
+    } else if (r > 0 && r < row && c == 0){
+        if (map.line[r+1].cell[c+1].state > DEAD) n ++;
+        if (map.line[r].cell[c+1].state > DEAD) n ++;
+        if (map.line[r-1].cell[c+1].state > DEAD) n ++;
+        if (map.line[r+1].cell[c].state > DEAD) n ++;
+        if (map.line[r-1].cell[c].state > DEAD) n ++;
+        if (map.line[r+1].cell[col-1].state > DEAD) n ++;
+        if (map.line[r].cell[col-1].state > DEAD) n ++;
+        if (map.line[r-1].cell[col-1].state > DEAD) n ++;
+    /* right side */
+    } else if (r > 0 && r < row && c == col - 1){
+        if (map.line[r+1].cell[0].state > DEAD) n ++;
+        if (map.line[r].cell[0].state > DEAD) n ++;
+        if (map.line[r-1].cell[0].state > DEAD) n ++;
+        if (map.line[r+1].cell[c].state > DEAD) n ++;
+        if (map.line[r-1].cell[c].state > DEAD) n ++;
+        if (map.line[r+1].cell[c-1].state > DEAD) n ++;
+        if (map.line[r].cell[c-1].state > DEAD) n ++;
+        if (map.line[r-1].cell[c-1].state > DEAD) n ++;
+    }
+    return n;
+}
diff --git a/src/struct.c b/src/struct.c
new file mode 100644 (file)
index 0000000..213b4bf
--- /dev/null
@@ -0,0 +1,23 @@
+#include "gol.h"
+
+extern int row,col;
+
+struct map newmap(void){
+    struct map tmp;
+    tmp.line = malloc(row*col*sizeof(struct cell));
+    for (int r = 0; r < row; r++){
+        tmp.line[r].cell = malloc(sizeof(struct cell)*col);
+    }
+    return tmp;
+}
+
+
+void freemap(struct map map){
+    for (int r = 0; r < row; r++){
+        for (int c = 0; c < col; c++){
+            free(map.line[r].cell);
+        }
+    }
+    free(map.line);
+    return;
+}
diff --git a/test/errortest.c b/test/errortest.c
new file mode 100644 (file)
index 0000000..aa3500e
--- /dev/null
@@ -0,0 +1,6 @@
+#include "gol.h"
+
+int main(int argc, char **argv){
+    errorcheck(NO_ERROR);
+    errorcheck(FLAG_ERROR);
+}
diff --git a/test/helptest.c b/test/helptest.c
new file mode 100644 (file)
index 0000000..7495e93
--- /dev/null
@@ -0,0 +1,5 @@
+#includ "gol.h"
+
+int main(int argc, char **argv){
+    help();
+}