main
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include "world.h"
5
6int west_of(World *world, int index) {
7 return (index % world->width == 0) ? index + (world->width-1) : index - 1;
8}
9
10int east_of(World *world, int index) {
11 return (index % world->width == (world->width-1)) ? index - (world->width-1) : index + 1;
12}
13
14int north_of(World *world, int index) {
15 return (index % world->width == index) ? world_number_of_cells(world) - world->width : index - world->width;
16}
17
18int south_of(World *world, int index) {
19 return (index >= (world_number_of_cells(world) - world->width)) ? index - (world_number_of_cells(world) - world->height) : index + world->width;
20}
21
22int north_west_of(World *world, int index) {
23 return west_of(world, north_of(world, index));
24}
25
26int north_east_of(World *world, int index) {
27 return east_of(world, north_of(world, index));
28}
29
30int south_west_of(World *world, int index) {
31 return west_of(world, south_of(world, index));
32}
33
34int south_east_of(World *world, int index) {
35 return east_of(world, south_of(world, index));
36}
37
38int world_number_of_cells(World *world) {
39 return world->width * world->height;
40}
41
42Cell* world_cell_at(World *world, int index) {
43 return &world->cells[sizeof(Cell) * index];
44}
45
46int world_neighbours(World *world, int index) {
47 Cell *west_cell = world_cell_at(world, west_of(world, index));
48 Cell *east_cell = world_cell_at(world, east_of(world, index));
49 Cell *north_cell = world_cell_at(world, north_of(world, index));
50 Cell *south_cell = world_cell_at(world, south_of(world, index));
51 Cell *north_west_cell = world_cell_at(world, north_west_of(world, index));
52 Cell *north_east_cell = world_cell_at(world, north_east_of(world, index));
53 Cell *south_west_cell = world_cell_at(world, south_west_of(world, index));
54 Cell *south_east_cell = world_cell_at(world, south_east_of(world, index));
55
56 return cell_alive(west_cell)
57 + cell_alive(east_cell)
58 + cell_alive(north_cell)
59 + cell_alive(south_cell)
60 + cell_alive(north_west_cell)
61 + cell_alive(north_east_cell)
62 + cell_alive(south_west_cell)
63 + cell_alive(south_east_cell);
64}
65
66World* world_create(int width, int height) {
67 int number_of_cells = width*height;
68 World *world = (World *)malloc(sizeof(World));
69
70 memset(world, 0, sizeof(World));
71
72 world->width = width;
73 world->height = height;
74 world->cells = cell_create(number_of_cells);
75 return world;
76}
77
78void world_each(World *world, each_cell callback){
79 for (int i = 0; i < world_number_of_cells(world); i++) {
80 callback(&world->cells[i]);
81 }
82}
83
84void choose_random_life(Cell *cell){
85 cell_change_life(cell, rand() % 2 == 0 ? true : false);
86}
87
88World* world_random(int width, int height){
89 World *world = world_create(width, height);
90 world_each(world, choose_random_life);
91 return world;
92}
93
94World* world_evolve(World *old_world) {
95 World *new_world = world_create(old_world->width, old_world->height);
96
97 for (int i = 0; i < world_number_of_cells(old_world); i++) {
98 int neighbours = world_neighbours(old_world, i);
99 bool lives = (world_cell_at(old_world, i)->alive && neighbours == 2) || neighbours == 3;
100 cell_change_life(world_cell_at(new_world, i), lives);
101 }
102
103 return new_world;
104}
105
106void world_print(World *world) {
107 for (int i = 0; i < world_number_of_cells(world); i++) {
108 if (i % world->width == 0) { printf("\n"); }
109 cell_print(&world->cells[i]);
110 }
111 printf("\n");
112}
113
114void world_destroy(World *world) {
115 free(world);
116}