Commit c48f9af

mo khan <mo@mokhan.ca>
2014-12-30 01:35:10
add tests for new world implementation.
1 parent 7c300d9
bin/test_game_of_life
Binary file
src/world.c
@@ -13,10 +13,32 @@ Cell* cell_create(int number_of_cells) {
   return cells;
 }
 
+int cell_alive(Cell cell) { return cell.alive == true ? 1 : 0; };
+
 int world_number_of_cells(World *world) {
   return world->width * world->height;
 }
 
+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 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)]);
+}
+
 World *world_create(int width, int height) {
   int number_of_cells = width*height;
   World *world = (World *)malloc(sizeof(World));
@@ -31,7 +53,13 @@ World *world_create(int width, int height) {
 World* world_evolve(World *world) {
   int number_of_cells = world_number_of_cells(world);
   for (int i = 0; i < number_of_cells; i++) {
-    world->cells[sizeof(Cell) * i].alive = false;
+    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;
+    } else {
+      world->cells[i].alive = neighbours == 3 ? true : false;
+    }
   }
   return world;
 }
src/world.h
@@ -11,7 +11,7 @@ typedef struct {
 } World;
 
 World* world_create(int width, int height);
-int world_neighbours(World* world, int index);
 World* world_evolve(World* world);
+int world_neighbours(World *world, int index);
 
 void world_display(World* world);
src/world_test.c
@@ -5,7 +5,7 @@
 
 #define run_test(function_name)\
   printf("%s\n", #function_name);\
-  function_name();
+function_name();
 
 void test_world_create() {
   int width = 3;
@@ -26,18 +26,99 @@ 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 = false;
+  world->cells[0].alive = true;
 
   world_evolve(world);
   assert(false == world->cells[0].alive);
   assert(false == world->cells[8].alive);
 }
 
+void any_live_cell_with_two_live_neighbours_lives_on_to_the_next_generation() {
+  /*{ 'x', 'x', 'x' },*/
+  /*{ ' ', ' ', ' ' },*/
+  /*{ ' ', ' ', ' ' },*/
+  World *world = world_create(3, 3);
+  world->cells[0].alive = true;
+  world->cells[1].alive = true;
+  world->cells[2].alive = true;
+
+  World* new_world = world_evolve(world);
+  assert(true == new_world->cells[1].alive);
+}
+
+void any_live_cell_with_three_live_neighbours_lives_on_to_the_next_generation() {
+  /*{ 'x', ' ', 'x' },*/
+  /*{ ' ', 'x', ' ' },*/
+  /*{ ' ', ' ', ' ' },*/
+  World *world = world_create(3, 3);
+  world->cells[0].alive = true;
+  world->cells[2].alive = true;
+  world->cells[4].alive = true;
+
+  World* new_world = world_evolve(world);
+  assert(true == new_world->cells[1].alive);
+}
+
+void any_live_cell_with_more_than_three_live_neighbours_dies_as_if_by_overcrowding() {
+  /*{ ' ', 'x', ' ' },*/
+  /*{ 'x', 'x', 'x' },*/
+  /*{ ' ', 'x', ' ' },*/
+  World *world = world_create(3, 3);
+  world->cells[1].alive = true;
+  world->cells[3].alive = true;
+  world->cells[4].alive = true;
+  world->cells[5].alive = true;
+  world->cells[7].alive = true;
+
+  World* new_world = world_evolve(world);
+  assert(false == new_world->cells[4].alive);
+}
+
+void any_dead_cell_with_exactly_three_live_neighbours_becomes_a_live_cell_as_if_by_reproduction(){
+  /*{ ' ', 'x', ' ' },*/
+  /*{ 'x', ' ', 'x' },*/
+  /*{ ' ', ' ', ' ' },*/
+  World *world = world_create(3, 3);
+  world->cells[1].alive = true;
+  world->cells[3].alive = true;
+  world->cells[5].alive = true;
+
+  World* new_world = world_evolve(world);
+  assert(true == new_world->cells[4].alive);
+}
+
+void it_returns_the_correct_number_of_living_neighbors() {
+  /*{ 'x', ' ', 'x' },*/
+  /*{ ' ', ' ', ' ' },*/
+  /*{ 'x', ' ', 'x' },*/
+  World *world = world_create(3, 3);
+  world->cells[0].alive = true;
+  world->cells[2].alive = true;
+  world->cells[6].alive = true;
+  world->cells[8].alive = true;
+
+  assert(world_neighbours(world, 0) == 3);
+  assert(world_neighbours(world, 1) == 4);
+  assert(world_neighbours(world, 2) == 3);
+  assert(world_neighbours(world, 3) == 4);
+  assert(world_neighbours(world, 4) == 4);
+  assert(world_neighbours(world, 5) == 4);
+  assert(world_neighbours(world, 6) == 3);
+  assert(world_neighbours(world, 7) == 4);
+  assert(world_neighbours(world, 8) == 3);
+}
+
 int main()
 {
   run_test(test_world_create);
   run_test(test_world_create_should_create_all_cells);
   run_test(any_live_cell_with_fewer_than_two_live_neighbours_dies_as_if_caused_by_under_population);
+  run_test(any_live_cell_with_two_live_neighbours_lives_on_to_the_next_generation);
+  run_test(any_live_cell_with_three_live_neighbours_lives_on_to_the_next_generation);
+  run_test(any_live_cell_with_more_than_three_live_neighbours_dies_as_if_by_overcrowding);
+  run_test(any_dead_cell_with_exactly_three_live_neighbours_becomes_a_live_cell_as_if_by_reproduction);
+  run_test(it_returns_the_correct_number_of_living_neighbors);
+
   printf("\nOK\n");
   return 0;
 }