From 7b6aecf53fc5b71da941af3f874e81f53cd6bb47 Mon Sep 17 00:00:00 2001 From: "Haoran S. Diao" <0@hairydiode.xyz> Date: Mon, 1 Apr 2019 19:37:32 -0400 Subject: functional conway's game of life with a glider --- .gitignore | 1 + Makefile | 2 ++ conway.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 conway.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe3d975 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +conway diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b41e815 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +conway: conway.c + gcc conway.c -o conway diff --git a/conway.c b/conway.c new file mode 100644 index 0000000..db4dd0a --- /dev/null +++ b/conway.c @@ -0,0 +1,103 @@ +#include +#define LOOP(col,line) \ +for (int j=0; j< 40; j++) { \ + for (int i=0; i < 80; i++) { \ + col \ + } \ + line \ +} + +/* + *Grid where everything is stored, 2nd least significant bit stores current + *state and least significant bit stores new state. + * The grid stores column position(x position) in the first field while row + * position( y position) is in the second field. As per c rules, this means that + * it is 80 wide by 40 tall, and the underlying datatype is a pointer to 80 + * pointers stored in an array, each of which point to 40 chars stored in an + * array. + * + *We use char because it's close enough to uint8_t w/o having to include the + * standard into library. + */ +char grid[80][40] = {{0,0,2},{2,0,2},{0,2,2},0}; + +/* + *determines whether a node should live(return 1) or die (return 0) based on + * it's current state + */ +int neighbor (int x, int y) { + /*neighbor count*/ + int count = 0; + /*loops through all neighbors based off of y offset j and x offset i*/ + for (int j = -1; j <= 1; j++) { + for (int i = -1; i <= 1; i++) { + /* makes sure to not count itself as a neighbor*/ + if (!((i == 0) && (j == 0))) { + /* + * modulo loops the grid back into itself + * the addition of the value is required + * otherwise strange nondeterministic behavior + * occurs + */ + if ( grid[(x+i + 80 )%80][(y+j + 40)%40] & 0x02) { + count++; + } + } + } + } + /* + * Switch determines the rules of conway's game of life + */ + switch (count) { + /* + * The current population of a cell determines whether it lives + * or die if it has 2 neighbors + */ + case 2: + if (grid[x][y] & 0x02) { + return 1; + } else { + return 0; + } + case 3: + return 1; + default: + return 0; + } +} +int main (int argc, char * argv[]) { + /* + * Stores the input character read from stdin. It's initialized to 0 + * because the main loop depends on it not being 'q' + */ + int r = 0; + /* + * A do at least once loop that iterates through the game. It tests for + * whether the character read from stdin is 'q' + */ + do { + /* + * Input from stdin, this is blocking so it also serves as a delay + */ + r = fgetc(stdin); + /* + * First it prints the current state stored in the 2nd least + * significant bit. X if it is present, Y if it is not. This + * loop is implemented as a macro b/c the entire loop has to be + * run 3 different times. The first argument is to be run for + * every cell while the 2nd one is to be run at the end of every + * row + */ + LOOP(if (grid[i][j] & 0x02) {printf("X");}else{printf(",");},printf("\n");); + /* + * Determines the current live/die state, then puts it into the + * least significant bit representing the new state of the cell + */ + LOOP(grid[i][j] = neighbor(i,j) | (grid[i][j] & 0x02);,); + /* + * Shifts the cell's state up, thereby making the new state the + * current state and the new new state 0. + */ + LOOP(grid[i][j] = grid[i][j] << 1;,); + } while (r != 'q'); +} -- cgit v1.1