lunes, 12 de noviembre de 2007

Cellular Automata

Ver Sketch



Esta es mi versión de "Conway's Game of Life" o de un cellular automata.

Primero se tiene una grilla donde cada pixel es una célula muerta. Se generan random cantidad de células vivas usando la variable "density" en posiciones elegidas de igual forma.
Una vez establecido el estado inicial, se empieza a evaluar el ciclo de vida de la siguiente forma:
  • Una célula muerta cobra vida cuando tiene mas de 3 células vecinas vivas.
  • Por el contrario, una célula viva muere cuando tiene menos de 2 (soledad) o mas de 3 (hacinamiento) células vecinas vivas.
Haciendo click se resetea el estado inicial y el ciclo vuelve a empezar.

Tengo pensado seguir trabajando sobre este sketch. Por ejemplo, se podría hacer con dos tipos diferentes de células (con colores diferentes) donde cada célula interactúa con las de su mismo tipo (o no, también se podría setear un ciclo de vida diferente cuando interactúan las de un tipo con las del otro).

El código a continuación:


// Defino un array para las células
int[][][] cells;

void setup() {
size(200, 200);
stroke(255);
frameRate(15);
reset();
}

void draw() {
// Con cada click se resetea el estado
if (mousePressed == true) {
reset();
}
// Comienza el ciclo de reproducción/muerte
ca();
}

// Función reset() resetea el estado
void reset() {
// Densidad de células en el estado inicial
float density = random(7);
cells = new int[width][height][2];
for (int i=0; i < width * height * density; i++) {
cells[(int)random(width)][(int)random(height)][1] = 1;
}
background(0);
}

// Función ca() dibuja los ciclos de reproducción/muerte
void ca() {
background(0);
// Primero, dibujo las células vivas
for (int x=0; x < width; x++) {
for (int y=0; y < height; y++) {
if (cells[x][y][1] == 1) {
point(x, y);
}
}
}

// Recorro cada célula para decidir si vive o muere
for (int x=0; x < width; x++) {
for (int y=0; y < height; y++) {
// Cantidad de vecinos vivos
int count = vecinos(x, y);
// Reproducción, solo células muertas con 3 vecinos vivos
if (count == 3 && cells[x][y][1] == 0) {
cells[x][y][1] = 1;
}
// Muerte, células vivas con menos de 2 o mas de 3 vecinos vivos
if ((count < 2 || count > 3) && cells[x][y][1] == 1) {
cells[x][y][1] = 0;
}
}
}
}

// Función vecinos() devuelve la cantidad de vecinos vivos de una célula
int vecinos(int x, int y) {
return cells[(x + 1) % width][y][1] +
cells[x][(y + 1) % height][1] +
cells[(x + width - 1) % width][y][1] +
cells[x][(y + height - 1) % height][1] +
cells[(x + 1) % width][(y + 1) % height][1] +
cells[(x + width - 1) % width][(y + 1) % height][1] +
cells[(x + width - 1) % width][(y + height - 1) % height][1] +
cells[(x + 1) % width][(y + height - 1) % height][1];
}

No hay comentarios: