This site requires JavaScript, please enable it in your browser!
Greenfoot back
JasonZhu
JasonZhu wrote ...

2014/5/14

Game of Life Iteration Trouble

JasonZhu JasonZhu

2014/5/14

#
I am coding a game of life where there are dead and alive cells. If the cell is dead and there are precisely 3 neighboring cells around it that are alive, the cells turns to life. If the cell is already alive, it needs specifically either 2 or 3 alive neighboring cells for it to stay alive, otherwise it dies. Here is my code: The exact rules are as follows: 1.Any live cell with fewer than two live neighbours dies, as if caused by under-population. 2.Any live cell with two or three live neighbours lives on to the next generation. 3.Any live cell with more than three live neighbours dies, as if by overcrowding. 4.Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. My code isn't working. I need help figuring out the problem. Thanks in advance.
    public void step() // each itteration of the game
    {
        Cell[][] copy = new Cell[worldSize][worldSize]; // create a new 2D array to copy the contents of the world.
        for(int r=0;r<worldSize;r++){ // copy the contents of the world 
            for(int c=0;c<worldSize;c++){
                copy[r][c] = new Cell();
                copy[r][c].setState(world[r][c].isAlive());
            }
        }
        for(int r=0;r<worldSize;r++){ // rules of the game of life
            for(int c=0;c<worldSize;c++){
                if(world[r][c].isAlive()){
                    if(neighAlive(r,c)!=2||neighAlive(r,c)!=3){
                        copy[r][c].setState(false);
                    }
                }else{
                    if(neighAlive(r,c)==3){
                        copy[r][c].setState(true);
                    }
                }
            }
        }
        for(int r=0;r<worldSize;r++){ // replace the world with the copy
            for(int c=0;c<worldSize;c++){
                world[r][c].setState(copy[r][c].isAlive());
            }
        }
    }

    private int neighAlive(int row, int col) // returns the number of alive neighboring cells in world[row][col]
    {
        int counter = 0;
        if(row==0){ // row edges
            if(col==0){ // top left corner
                if(world[row][col+1].isAlive())counter++;
                if(world[row+1][col].isAlive())counter++;
                if(world[row+1][col+1].isAlive())counter++;
            }else
            if(col==worldSize-1){ // top right corner
                if(world[row][col-1].isAlive())counter++;
                if(world[row+1][col].isAlive())counter++;
                if(world[row+1][col-1].isAlive())counter++;
            }else{ // top row, anywhere not including the two corners on the left edge and right edge
                if(world[row][col+1].isAlive())counter++;
                if(world[row][col-1].isAlive())counter++;
                if(world[row+1][col+1].isAlive())counter++;
                if(world[row+1][col].isAlive())counter++;
                if(world[row+1][col-1].isAlive())counter++;
            }
        }else
        if(row==worldSize-1){
            if(col==0){ // bottom left corner
                if(world[row][col+1].isAlive())counter++;
                if(world[row-1][col].isAlive())counter++;
                if(world[row-1][col+1].isAlive())counter++;
            }else
            if(col==worldSize-1){ // bottom right corner
                if(world[row][col-1].isAlive())counter++;
                if(world[row-1][col].isAlive())counter++;
                if(world[row-1][col-1].isAlive())counter++;
            }else{ // bottom row, anywhere not including the two corners on the left edge and right edge
                if(world[row][col+1].isAlive())counter++;
                if(world[row][col-1].isAlive())counter++;
                if(world[row-1][col+1].isAlive())counter++;
                if(world[row-1][col].isAlive())counter++;
                if(world[row-1][col-1].isAlive())counter++;
            }
        }else
        if(col==0){ // column edges
            if(row==0){ // top corner of left-most column
                if(world[row+1][col].isAlive())counter++;
                if(world[row][col+1].isAlive())counter++;
                if(world[row+1][col+1].isAlive())counter++;
            }else
            if(row==worldSize-1){ // bottom corner of left-most column
                if(world[row-1][col].isAlive())counter++;
                if(world[row][col+1].isAlive())counter++;
                if(world[row-1][col+1].isAlive())counter++;
            }else{ // left-most column, anywhere not including the top and bottom corners
                if(world[row+1][col].isAlive())counter++;
                if(world[row-1][col].isAlive())counter++;
                if(world[row+1][col+1].isAlive())counter++;
                if(world[row][col+1].isAlive())counter++;
                if(world[row-1][col+1].isAlive())counter++;
            }
        }else
        if(col==worldSize-1){
            if(row==0){ // top corner of right-most column
                if(world[row-1][col].isAlive())counter++;
                if(world[row][col+1].isAlive())counter++;
                if(world[row-1][col+1].isAlive())counter++;
            }else
            if(row==worldSize-1){ // bottom corner of right-most column
                if(world[row-1][col].isAlive())counter++;
                if(world[row][col-1].isAlive())counter++;
                if(world[row-1][col-1].isAlive())counter++;
            }else{ // right-most column, anywhere not including the top and bottom corners
                if(world[row+1][col].isAlive())counter++;
                if(world[row-1][col].isAlive())counter++;
                if(world[row+1][col-1].isAlive())counter++;
                if(world[row][col-1].isAlive())counter++;
                if(world[row-1][col-1].isAlive())counter++;
            }
        }else{ // anywhere else on the cell grid not including the edges
            for(int r=row-1;r<=row+1;r++){
                for(int c=col-1;c<=col+1;c++){
                    if(world[r][c].isAlive()){
                        counter++;
                    }
                }
            }
            if(world[row][col].isAlive()){ // subtract the cell itself if it was alive as the nested loops included it
                counter-=1;
            }
        }
        return counter;
    }
JasonZhu JasonZhu

2014/5/14

#
I took out the if blocks and left strictly the for loop and the last if statement and I got an array out of bounds error even though I'm placing alive cells in the center of my grid. I honestly see no reason for getting this error...
JasonZhu JasonZhu

2014/5/14

#
Nevermind, I see why I'm getting the error now, but after inputting patterns from: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life I still don't get the expected results.
JasonZhu JasonZhu

2014/5/14

#
Omg... My instructor pointed it out... 13. if(neighAlive(r,c)!=2||neighAlive(r,c)!=3){ 14. copy.setState(false); 15. } need to be changed to 13. if(neighAlive(r,c)<2||neighAlive(r,c)>3){ 14. copy.setState(false); 15. } I thought that what I had stated that if it was not equal to 3 or 2, meaning if its anything besides that, it would die.
danpost danpost

2014/5/14

#
Wow. That is a lot of code in the 'neighAlive' method. How about this:
private int neighAlive(int row, int col)
{
    int counter = 0;
    for (int dr=-1; dr < 2; dr++)
    {
        for (int dc = -1; dc < 2; dc++) // for all possible surrounding cells
        {
            if (row+dr >= 0 && row+dr < worldSize && // row in grid
                col+dc >= 0 && col+dc < worldSize && // col in grid
                (dr != 0 || dc != 0) && // not self 
                world[row+dr][col+dc].isAlive()) // and alive
            { 
                counter++;
            }
        }
    }
    return counter;
}
Whenever you find yourself writing line after line of similar code, look for an easier way to do it -- there usually is one. Shorter code is easier to write, understand, and follow. Also, there is less chance for bugs to creep in; and when they do, they are much easier to find and squash.
danpost danpost

2014/5/14

#
JasonZhu wrote...
I thought that what I had stated that if it was not equal to 3 or 2, meaning if its anything besides that, it would die.
Think about this: If it is not 2, then it could be 3; and if it is not 3, it could be 2. One OR the other is ALWAYS true. A simple fix could also have been to change '||' to '&&', 'and'ing them. If it is not 2 AND it is not 3 ...
JasonZhu JasonZhu

2014/5/15

#
Thank you for your suggestions. I understand it now. And thanks for a simpler method, I didn't realize that it took that much room until you pointed it out.
You need to login to post a reply.