commit 858028fa19331fbf764f756c787e6daa80f59a94
parent a7f420eb10d5e51045b48bda1bc749916ddc21e4
Author: Anders Damsgaard <anders.damsgaard@geo.au.dk>
Date:   Fri,  7 Mar 2014 16:38:45 +0100
Added memory management, conway's rules
Diffstat:
| M | Makefile |  |  | 7 | +++---- | 
| M | main.c |  |  | 31 | +++++++++++++++++++++++++++++-- | 
| A | rules.c |  |  | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| A | rules.h |  |  | 8 | ++++++++ | 
| A | utility.c |  |  | 37 | +++++++++++++++++++++++++++++++++++++ | 
| A | utility.h |  |  | 8 | ++++++++ | 
6 files changed, 156 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,13 +1,12 @@
 CFLAGS=-Wall -pedantic -g -O2
 #LDLIBS=-lm
 
-BIN=gol
+BIN=gameoflife
 
-$(BIN): main.o 
+$(BIN): main.o utility.o rules.o
 	$(CC) $(CFLAGS) $(LDLIBS) $^ -o $@
 
-#main.o: file_io.h utility.h boundary.h solution.h
-#file_io.o: utility.h
+main.o: utility.h utility.c rules.h rules.c
 
 clean:
 	$(RM) *.o
diff --git a/main.c b/main.c
@@ -2,15 +2,20 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include "utility.h"
+#include "rules.h"
 
 #define VERSION 0.1
 
 int main(int argc, char **argv)
 {
     int **cells;
+    int **neighbors;
     int nx = 10;
     int ny = 10;
     int c;
+    unsigned int it = 0;
+    int world_is_dead = 0;
 
     while ((c = getopt(argc, argv, "hv")) != -1)
         switch (c)
@@ -23,8 +28,7 @@ int main(int argc, char **argv)
             return 0;
             break;
         case 'v':
-            printf("%s: Conway's Game of Life,"
-                    "version %.1f\n"
+            printf("%s: Conway's Game of Life, version %.1f\n"
                     "Written by Anders Damsgaard, "
                     "https://github.com/anders-dc/game-of-life\n", argv[0], VERSION);
             return 0;
@@ -47,7 +51,30 @@ int main(int argc, char **argv)
 
     printf("Grid dimensions: %dx%d\n", nx, ny);
 
+    allocate_matrix(&cells, nx, ny);
+    allocate_matrix(&neighbors, nx, ny);
 
+    random_population(cells, nx, ny, 0.5);
+
+    print_matrix("cells", cells, nx, ny);
+
+    /*while ((c = getchar()) != 'q') {*/
+    while (world_is_dead == 0) {
+
+        world_is_dead = find_neighbor_count(cells, neighbors, nx, ny);
+        cell_transitions(cells, neighbors, nx, ny);
+
+        printf("it = %d\n", it);
+        print_matrix("neighbors", neighbors, nx, ny);
+        print_matrix("cells", cells, nx, ny);
+
+        sleep(1);
+
+        it++;
+    }
+
+    free_matrix(&cells, nx);
+    free_matrix(&neighbors, nx);
 
     return 0;
 }
diff --git a/rules.c b/rules.c
@@ -0,0 +1,71 @@
+#include <stdlib.h>
+#include <time.h>
+
+/* Populate a 2D array with 0's and 1's in a pseudo-random fashion.
+ * The population will be ratio*100% consisting of 1's
+ */
+void random_population(int **cells, int nx, int ny, double ratio)
+{
+    int i, j;
+    srand(time(NULL));
+
+    for (i=0; i<nx; i++) {
+        for (j=0; j<ny; j++) {
+            if ((double)rand()/RAND_MAX < ratio)
+                cells[i][j] = 1;
+            else
+                cells[i][j] = 0;
+        }
+    }
+}
+
+int find_neighbor_count(int **cells, int **neighbors, int nx, int ny)
+{
+    int world_is_dead = 0;
+    int i, j, x, y;
+    int nneighbors;
+
+    for (i=1; i<nx-1; i++) {
+        for (j=1; j<ny-1; j++) {
+            nneighbors = 0;
+
+            for (x=-1; x<2; x++) {
+                for (y=-1; y<2; y++) {
+                    if (x != 0 && y != 0) {
+                        nneighbors += cells[i+x][j+y];
+                    }
+                }
+            }
+            neighbors[i][j] = nneighbors;
+            if (nneighbors > 0)
+                world_is_dead = 0;
+        }
+    }
+
+    if (world_is_dead == 1)
+        return 1;
+    else
+        return 0;
+}
+
+void cell_transitions(int **cells, int **neighbors, int nx, int ny)
+{
+    int i, j, nneighbors;
+    for (i=1; i<nx-1; i++) {
+        for (j=1; j<ny-1; j++) {
+            nneighbors = neighbors[i][j];
+
+            if (cells[i][j] == 1) { /* alive */
+                if (nneighbors < 2)      /* under-population */
+                    cells[i][j] = 0;
+                else if (nneighbors > 3) /* over-population */
+                    cells[i][j] = 0;
+                else                     /* survive */
+                    cells[i][j] = 1;
+            } else {                /* dead */
+                if (nneighbors == 3)     /* reproduction */
+                    cells[i][j] = 1;
+            }
+        }
+    }
+}
diff --git a/rules.h b/rules.h
@@ -0,0 +1,8 @@
+#ifndef RULES_H_
+#define RULES_H_
+
+void random_population(int **cells, int nx, int ny, double ratio);
+int find_neighbor_count(int **cells, int **neighbors, int nx, int ny);
+void cell_transitions(int **cells, int **neighbors, int nx, int ny);
+
+#endif
diff --git a/utility.c b/utility.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int allocate_matrix(int ***M, int nx, int ny)
+{
+    int i;
+    (*M) = (int**) malloc(sizeof(double*)*nx);
+    if (*M == NULL)
+        return 1;
+
+    for (i=0; i<nx; i++) {
+        (*M)[i] = (int*) malloc(sizeof(double)*ny);
+        if ((*M)[i] == NULL)
+            return 1;
+    }
+    return 0;
+}
+
+void free_matrix(int ***M, int nx)
+{
+    int i;
+    for (i=0; i<nx; i++)
+        free((*M)[i]);
+    free(*M);
+}
+
+void print_matrix(char* description, int **M, int nx, int ny)
+{
+    int i, j;
+    printf("%s:\n", description);
+    for (j=0; j<ny; j++) {
+        for (i=0; i<nx; i++) {
+            printf("%d ", M[i][j]);
+        }
+        printf("\n");
+    }
+}
diff --git a/utility.h b/utility.h
@@ -0,0 +1,8 @@
+#ifndef UTILITY_H_
+#define UTILITY_H_
+
+int allocate_matrix(int ***M, int nx, int ny);
+void free_matrix(int ***M, int nx);
+void print_matrix(char* description, int **M, int nx, int ny);
+
+#endif