--- /dev/null
+#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);
+}
--- /dev/null
+#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);
--- /dev/null
+#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;
+}