# Cellular Automata The cellular automata algorithm creates organic pattenrs amongst a collection of points. It does so by designating cells as "alive" or "dead" and running a simulation for the alive cells to grow into neighboring cells. Similarly the dead cells also spread. This simulation is run a variable number of times and afterwards there are organic blobs that have emereged that resemble natural ocurrances. ![](/images/cellular.jpg) Cellular automata lends itself to the procedural generation of islands, caves, growths etc. ## Implementation Steps: 1. Start by designating some variables for sampling, chances a cell starts alive, maximum times it can grow or die, number of simulation steps. 2. Iterate across your cell map designating each cell as alive or dead based on the chance a cell is alive. 3. For number of simulation steps: 1. Iterate across the map and for each cell count the number of alive neighbor cells 2. If I am on a dead cell, and the number of dead neighbors is less than the dead maximum, designate me dead as well (essentially we are collapsing) 3. If I am on an alive cell and alive neighbors is less than alive maximum, designate me alive as well (essentially we are growing) 4. After all simulations are complete the cellular automata has been applied, you can query a map position for if it is alive or dead and visualize or whatnot ## Example in C I broke the algorirthm up into a few functions to clarify the steps: ### Implementation Body ```c /////////////////////////// // CELLULAR AUTOMATA START void dm_cellular_automata(int width, int height, void (*on_solid)(int, int), void (*on_open)(int, int)) { double alive_chance = 0.4; int death_max = 3; int birth_max = 4; int steps = 2; dm_cellular_automata_detail(width, height, on_solid, on_open, alive_chance, death_max, birth_max, steps); } void dm_cellular_automata_detail(int width, int height, void (*on_solid)(int, int), void (*on_open)(int, int), double alive_chance, int death_max, int birth_max, int steps) { int map[width * height]; dm_cella_init(map, width, height, alive_chance); for (int i=0; i 0){ //See if it should die or stay solid if (nbs < deathLimit) map[index] = 0; else map[index] = 1; } else { //See if it should become solid if (nbs > birthLimit) map[index] = 1; else map[index] = 0; } } } } int dm_cella_count_alive_neighbors(int *map, int x, int y, int width, int height) { int count = 0; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { int nb_x = i+x; int nb_y = j+y; int nb_index = nb_y * width + nb_x; if (i == 0 && j == 0) continue; //If it's at the edges, consider it to be solid (you can try removing the count = count + 1) if (nb_x < 0 || nb_y < 0 || nb_x >= width || nb_y >= height) count = count + 1; else if (map[nb_index] == 1) count = count + 1; } } return count; } // CELLULAR AUTOMATA END /////////////////////////// ``` ### Example Usage This produces the headline image above. ```c int main(void) { char *red = "\033[0;31m"; char *green = "\033[0;32m"; char *blue = "\033[0;34m"; char *def = "\033[0m"; int seed = 123; do { printf("SEED %d\n", seed); dm_seed(seed); seed++; int width = 53; int height = 32; int map[width * height]; void on_solid(int x, int y) { map[y * width + x] = 1; } void on_open(int x, int y) { map[y * width + x] = 0; } dm_cellular_automata(width, height, on_solid, on_open); for (int r=0; r < height; r++) { for (int c=0; c < width; c++) { int index = r * width + c; if (map[index] == 0) printf("%so %s", green, def); else printf(". "); } printf("\n"); } getchar(); } while(true); return 0; } ```