Commit c48f9af
Changed files (4)
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;
}