summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaoran S. Diao <0@hairydiode.xyz>2019-04-01 19:37:32 -0400
committerHaoran S. Diao <0@hairydiode.xyz>2019-04-01 19:37:32 -0400
commit7b6aecf53fc5b71da941af3f874e81f53cd6bb47 (patch)
tree50aabdbd5b0704cfbca3f2ffe8fa02cc5893e039
functional conway's game of life with a glider
-rw-r--r--.gitignore1
-rw-r--r--Makefile2
-rw-r--r--conway.c103
3 files changed, 106 insertions, 0 deletions
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 <stdio.h>
+#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');
+}