Game Of Life implemented with for-loops and a boolean-array 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 &lt; width - 1; x++) {
        for (int y = 1; y &lt; height - 1; y++) {
            int neighbors = 0;

            // Check surrounding cells.
            for (int neighborX = x - 1; neighborX &lt;= x + 1; neighborX++) {
                for (int neighborY = y - 1; neighborY &lt;= 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.
I'd start it with a Cell and a Grid class and probably a two-dimensional Cell array field in the Grid.  Cell provides type-safety and more readable code while  probably contains only a boolean flag. 

Anyway, this implementation can be improved. I'd extract out a List&lt;Integer&gt; getSurroundingCells(int cellIndex) and an int countLiveCells(final List&lt;Integer&gt; cellIndexes) method. A boolean getNextValue(int cellIndex, boolean oldValue, int liveNeighborCount) also could help.