2

I have the following logic code for my Game of Life application in Java. I have the problem that the rules do not act like the default Conway's Game of Life rules. I have read up on them on Wikipedia, and they are the following;

  • Any live cell with fewer than two live neighbours dies, as if caused by under-population.
  • Any live cell with two or three live neighbours lives on to the next generation.
  • Any live cell with more than three live neighbours dies, as if by overcrowding.
  • Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

I have attempted to duplicate these rules in the following code, but it acts unlike the normal Conway' Game of Life;

int surroundingLife = 0;
if (lifeMap[cX+1][cY]) { //Right
    surroundingLife++;
}
if (lifeMap[cX-1][cY]) { // Left
    surroundingLife++;
}
if (lifeMap[cX][cY+1]) { // Above
    surroundingLife++;
}
if (lifeMap[cX][cY-1]) { // Below
    surroundingLife++;
}
if (lifeMap[cX-1][cY-1]) { // Bottom left
    surroundingLife++;
}
if (lifeMap[cX+1][cY+1]) { // Top Right
    surroundingLife++;
}
if (lifeMap[cX-1][cY+1]) { // Some other corner (I don't know which one)
    surroundingLife++;
}
if (lifeMap[cX+1][cY-1]) { // Yet another corner (I don't know which one)
    surroundingLife++;
}
if (running) {
    // Logic for life
    if (surroundingLife < 2 && lifeMap[cX][cY]) {// Rule 1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
        lifeMap[cX][cY] = false;
    } else if (surroundingLife == 2 && lifeMap[cX][cY]) { // Rule 2. Any live cell with two or three live neighbours lives on to the next generation.
        lifeMap[cX][cY] = true;
    } else if (surroundingLife == 3 && lifeMap[cX][cY]) { // Rule 3. Same as above
        lifeMap[cX][cY] = true;
    } else if (surroundingLife > 3 && lifeMap[cX][cY]) { // Rule 4. Any live cell with more than three live neighbours dies, as if by overcrowding.
        lifeMap[cX][cY] = false;
    } else if (surroundingLife == 3 && !lifeMap[cX][cY]) { // Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
        lifeMap[cX][cY] = true;
    }
}   

This is how it looks after running a couple of generations;

GameOfBugs, or BugsOfLife.

It reminds me of the 'maze' ruleset, which is odd.

I don't believe there is a fault with my surroundingLife calculator, as it returns 8 when entities have 8 others surrounding them. Is the problem due to me looping through Y then X?

stealthjong
  • 10,858
  • 13
  • 45
  • 84
Jack Wilsdon
  • 6,706
  • 11
  • 44
  • 87
  • possible duplicate of [The game of life(Conway's game) - how to check for cell neighbours](http://stackoverflow.com/questions/8364301/the-game-of-lifeconways-game-how-to-check-for-cell-neighbours) – Paul Gregoire Nov 23 '14 at 01:02

1 Answers1

10

The problem is that you are modifying the grid in the same pass as you are evaluating what needs to change. Each time you change a cell, you are affecting the outcome of all future tests in the same pass that border that cell.

You need to make a copy of the grid. Always test (read) from that copy, and apply changes (write) to the original.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • 2
    So have 2 grids, and sync them after the generation has completed? – Jack Wilsdon Jan 03 '13 at 15:59
  • 3
    I wish I had a nickel for every time I've seen this mistake; heck I probably did it myself the first time. – Dave Newton Jan 03 '13 at 15:59
  • You can do that, or you can use the approach I've suggested. Just make a copy of the array at the beginning of each pass, and use that array for all of your tests. Apply the actual changes to the original array. – cdhowie Jan 03 '13 at 15:59
  • I have done as suggested, but still get the problem. Here is my new code; https://gist.github.com/098a5b811a3a4cc7e124 – Jack Wilsdon Jan 03 '13 at 16:02
  • @HighPerformanceMark You can do that too, if after each pass you go back and copy the data from `old` to `new` before you begin, otherwise you will be making a pass using stale data. – cdhowie Jan 03 '13 at 16:03
  • It may be the best option but you don't "***need** to make a copy of the grid.*" You could make it work with one grid - but it would probably need 2 passes for each generation. – ypercubeᵀᴹ Jan 03 '13 at 16:06
  • 3
    @jackwilsdon You did not make a copy of the array, you made a copy of the array reference. Both variables are still pointing to the same array. – cdhowie Jan 03 '13 at 16:06
  • @cdhowie What do you mean? – Jack Wilsdon Jan 03 '13 at 16:06
  • @jackwilsdon `checkCopy = lifeMap;` This does not create a new copy of the array. It copies the reference to the array from one variable to another. `checkCopy` and `lifeMap` are both references to the *same array*. Changes you make to one will reflect in the other, because they are actually targeting the same object. – cdhowie Jan 03 '13 at 16:07
  • When you type `checkCopy = lifeMap;` both objects still point to the same array, and you're still editing only one array. You have to make a new object and copy the values into that one. – Lynn Jan 03 '13 at 16:07
  • I was thinking more of defining `lifeMap[m][n][2]` and setting `old = 1`, `new = 2`, then run the game one step updating `lifeMap[][][new]` from `lifeMap[][][old]`, then swap `old = 2`, `new = 1` and continue. I don't see any need for copying arrays of data. – High Performance Mark Jan 03 '13 at 16:09
  • @HighPerformanceMark I see what you mean, yes, that would also work. I was momentarily forgetting that each pass will update *every* cell. – cdhowie Jan 03 '13 at 16:10
  • using `checkCopy = lifeMap.clone();` still modifies `lifeMap` when I do `checkCopy[20][20] = true`. How do I completely disassociate the arrays? – Jack Wilsdon Jan 03 '13 at 16:11
  • 1
    @jackwilsdon Cloning the array should be enough to disassociate the arrays. If that's not working then there is another problem somewhere else. – cdhowie Jan 03 '13 at 16:18
  • Using a for loop to go through the code works fine; https://gist.github.com/4444628 – Jack Wilsdon Jan 03 '13 at 16:18
  • 1
    @jackwilsdon If you're still having trouble, [let's chat over here](http://chat.stackoverflow.com/rooms/22135/game-of-life-rules-not-working-properly) instead of cluttering this answer with comments. – cdhowie Jan 03 '13 at 16:25