Commit 2ce0728

mo khan <mo@mokhan.ca>
2014-12-30 02:02:25
extract cell class and fix broken test.
1 parent c48f9af
src/cell.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cell.h"
+
+Cell* cell_create(int number_of_cells) {
+  Cell *cells = malloc(sizeof(Cell) * number_of_cells);
+  memset(cells, 0, sizeof(Cell) * number_of_cells);
+
+  for (int i = 0; i < number_of_cells; i++) {
+    cells[sizeof(Cell) * i].alive = false;
+  }
+  return cells;
+}
+
+int cell_alive(Cell cell) { 
+  return cell.alive == true ? 1 : 0; 
+};
src/cell.h
@@ -0,0 +1,8 @@
+#include <stdbool.h>
+
+typedef struct {
+  bool alive;
+} Cell;
+
+Cell* cell_create(int number_of_cells);
+int cell_alive(Cell cell);
src/world.c
@@ -3,40 +3,64 @@
 #include <string.h>
 #include "world.h"
 
-Cell* cell_create(int number_of_cells) {
-  Cell *cells = malloc(sizeof(Cell) * number_of_cells);
-  memset(cells, 0, sizeof(Cell) * number_of_cells);
+int world_number_of_cells(World *world) {
+  return world->width * world->height;
+}
 
-  for (int i = 0; i < number_of_cells; i++) {
-    cells[sizeof(Cell) * i].alive = false;
-  }
-  return cells;
+int west_of(World *world, int index) {
+  return (index % world->width == 0) ? index + (world->width-1) : index - 1;
 }
 
-int cell_alive(Cell cell) { return cell.alive == true ? 1 : 0; };
+int east_of(World *world, int index) {
+  return (index % world->width == (world->width-1)) ? index - (world->width-1) : index + 1;
+}
 
-int world_number_of_cells(World *world) {
-  return world->width * world->height;
+int north_of(World *world, int index) {
+  return (index % world->width == index) ? world_number_of_cells(world) - world->width : index - world->width;
 }
 
-int west_of(World *world, int index) { return (index % world->width == 0) ?  index + (world->width-1) : index - 1; }
-int east_of(World *world, int index) { return (index % world->width == (world->width-1)) ? index - (world->width-1) : index + 1; }
-int north_of(World *world, int index) { return (index % world->width == index) ? world_number_of_cells(world) - world->width : index - world->width; }
-int south_of(World *world, int index) { return (index >= (world_number_of_cells(world) - world->width)) ? index - (world_number_of_cells(world) - world->height) : index + world->width; }
-int north_west_of(World *world, int index) { return west_of(world, north_of(world, index)); }
-int north_east_of(World *world, int index) { return east_of(world, north_of(world, index)); }
-int south_west_of(World *world, int index) { return west_of(world, south_of(world, index)); }
-int south_east_of(World *world, int index) { return east_of(world, south_of(world, index)); }
+int south_of(World *world, int index) {
+  return (index >= (world_number_of_cells(world) - world->width)) ? index - (world_number_of_cells(world) - world->height) : index + world->width;
+}
+
+int north_west_of(World *world, int index) {
+  return west_of(world, north_of(world, index));
+}
+
+int north_east_of(World *world, int index) {
+  return east_of(world, north_of(world, index));
+}
+
+int south_west_of(World *world, int index) {
+  return west_of(world, south_of(world, index));
+}
+
+int south_east_of(World *world, int index) {
+  return east_of(world, south_of(world, index));
+}
+
+Cell world_cell_at(World *world, int index) {
+  return world->cells[sizeof(Cell) * index];
+}
 
 int world_neighbours(World *world, int index) {
-  return cell_alive(world->cells[sizeof(Cell) * west_of(world, index)])
-    + cell_alive(world->cells[sizeof(Cell) * east_of(world, index)])
-    + cell_alive(world->cells[sizeof(Cell) * north_of(world, index)])
-    + cell_alive(world->cells[sizeof(Cell) * south_of(world, index)])
-    + cell_alive(world->cells[sizeof(Cell) * north_west_of(world, index)])
-    + cell_alive(world->cells[sizeof(Cell) * north_east_of(world, index)])
-    + cell_alive(world->cells[sizeof(Cell) * south_west_of(world, index)])
-    + cell_alive(world->cells[sizeof(Cell) * south_east_of(world, index)]);
+  Cell west_cell = world_cell_at(world, west_of(world, index));
+  Cell east_cell = world_cell_at(world, east_of(world, index));
+  Cell north_cell = world_cell_at(world, north_of(world, index));
+  Cell south_cell = world_cell_at(world, south_of(world, index));
+  Cell north_west_cell = world_cell_at(world, north_west_of(world, index));
+  Cell north_east_cell = world_cell_at(world, north_east_of(world, index));
+  Cell south_west_cell = world_cell_at(world, south_west_of(world, index));
+  Cell south_east_cell = world_cell_at(world, south_east_of(world, index));
+
+  return cell_alive(west_cell)
+    + cell_alive(east_cell)
+    + cell_alive(north_cell)
+    + cell_alive(south_cell)
+    + cell_alive(north_west_cell)
+    + cell_alive(north_east_cell)
+    + cell_alive(south_west_cell)
+    + cell_alive(south_east_cell);
 }
 
 World *world_create(int width, int height) {
@@ -52,14 +76,14 @@ World *world_create(int width, int height) {
 
 World* world_evolve(World *world) {
   int number_of_cells = world_number_of_cells(world);
+  World *new_world = world_create(world->width, world->height);
   for (int i = 0; i < number_of_cells; i++) {
     int neighbours = world_neighbours(world, i);
-    printf("%d: %d\n", i, neighbours);
     if (world->cells[i*sizeof(Cell)].alive == true) {
-      world->cells[i].alive = (neighbours >= 2 && neighbours <= 3) ? true : false;
+      new_world->cells[i].alive = (neighbours >= 2 && neighbours <= 3) ? true : false;
     } else {
-      world->cells[i].alive = neighbours == 3 ? true : false;
+      new_world->cells[i].alive = neighbours == 3 ? true : false;
     }
   }
-  return world;
+  return new_world;
 }
src/world.h
@@ -1,8 +1,4 @@
-#include <stdbool.h>
-
-typedef struct {
-  bool alive;
-} Cell;
+#include "cell.h"
 
 typedef struct {
   int width;
@@ -13,5 +9,3 @@ typedef struct {
 World* world_create(int width, int height);
 World* world_evolve(World* world);
 int world_neighbours(World *world, int index);
-
-void world_display(World* world);
src/world_test.c
@@ -28,9 +28,9 @@ void any_live_cell_with_fewer_than_two_live_neighbours_dies_as_if_caused_by_unde
   World *world = world_create(3, 3);
   world->cells[0].alive = true;
 
-  world_evolve(world);
-  assert(false == world->cells[0].alive);
-  assert(false == world->cells[8].alive);
+  World *new_world = world_evolve(world);
+  assert(false == new_world->cells[0].alive);
+  assert(false == new_world->cells[8].alive);
 }
 
 void any_live_cell_with_two_live_neighbours_lives_on_to_the_next_generation() {
@@ -70,6 +70,10 @@ void any_live_cell_with_more_than_three_live_neighbours_dies_as_if_by_overcrowdi
   world->cells[5].alive = true;
   world->cells[7].alive = true;
 
+  assert(5 == world_neighbours(world, 0));
+  assert(4 == world_neighbours(world, 1));
+  assert(4 == world_neighbours(world, 4));
+
   World* new_world = world_evolve(world);
   assert(false == new_world->cells[4].alive);
 }
Makefile
@@ -1,5 +1,5 @@
 default: src/*.c src/*.h
 	rm -fr bin
 	mkdir -p bin
-	gcc -std=c99 -Wall -o bin/test_game_of_life src/world_test.c src/world.c src/print.c
+	gcc -std=c99 -Wall -o bin/test_game_of_life src/world_test.c src/world.c src/cell.c src/print.c
 	./bin/test_game_of_life