2
\$\begingroup\$

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.

asked Dec 6, 2011 at 19:51
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

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<Integer> getSurroundingCells(int cellIndex) and an int countLiveCells(final List<Integer> cellIndexes) method. A boolean getNextValue(int cellIndex, boolean oldValue, int liveNeighborCount) also could help.

answered Dec 6, 2011 at 20:54
\$\endgroup\$
1
  • 1
    \$\begingroup\$ While I hesitated to write classes for it, you're right. Thinking about it I came to the conclusion that it would ease things in the end, f.e. handling of neighbors and the new generation. I'll do that next. \$\endgroup\$ Commented Dec 7, 2011 at 11:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.