There's a Follow-up: Game Of Life rewritten into two classes, PetriDish and Cell
I wrote an implementation of the Game Of Life using the easiest approach, a bunch of loops and a boolean array. Yet I feel like I missed something very elemental.
The basic implementation is:
- Check the old generation with loops
- Check each neighbor of each cell...with loops
- Set the status in the generation
- Copy the new generation over the old one
This seems to have some serious downsides, especially the heavy use of loops which makes me a little bit itchy.
private boolean[] cells; // Will be set at construction
private int width;
private int height;
/**
* Evolve into the next nextGeneration.
*/
private void doGeneration() {
boolean[] nextGeneration = new boolean[cells.length];
for (int x = 1; x < width - 1; x++) {
for (int y = 1; y < height - 1; y++) {
int neighbors = 0;
// Check surrounding cells.
for (int neighborX = x - 1; neighborX <= x + 1; neighborX++) {
for (int neighborY = y - 1; neighborY <= y + 1; neighborY++) {
if (neighborX != x || neighborY != y) {
if (cells[neighborX * width + neighborY]) {
neighbors++;
}
}
}
}
int idx = x * width + y;
switch (neighbors) {
case 0:
case 1:
nextGeneration[idx] = false;
break;
case 2:
nextGeneration[idx] = cells[idx];
break;
case 3:
nextGeneration[idx] = true;
break;
default:
nextGeneration[idx] = false;
break;
}
}
}
cells = nextGeneration;
}
Edit: The whole application (Slick dependent for input and drawing) can be found at GitHub.
Edit2: There's a bug in the above code. The index should of course be y * width + x
. I stumbled against that yesterday when I tried to handle non-square grids, but I just realized what was wrong some minutes ago while riding the bus.