'Java Conway Game of life

My program is Conway Game of life, the rules are:

  1. Any live cell with fewer than two live neighbors dies as if caused by underpopulation.
  2. Any live cell with two or three live neighbors lives on to the next generation.
  3. Any live cell with more than three live neighbors dies, as if by overpopulation.
  4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

I was able to check for alive neighbors in a single row my problem is checking for alive neighbors in the column and to see whether the next generation lives or dies while checking column, my code below demonstrates what I get, Where 1 represent a live cell and 0 represents a dead cell.

public static int[][] nextGeneration(int inputGrid[][]) {
                int height = 10, width = 10;
                int[][] future = new int[height][width];     
    
    for (int x = 1; x < height - 1; x++) {
                    for (int y = 1; y < width - 1; y++) {
                        int aliveNeighbours = 0;
                        for (int i = -1; i <= 1; i++)
                            for (int j = -1; j <= 1; j++)
                                aliveNeighbours += inputGrid[x + i][y + j];
        
                        aliveNeighbours -= inputGrid[x][y];
                        if ((inputGrid[x][y] == 1) && (aliveNeighbours < 2))
                            future[x][y] = 0;
            
                            else if (((inputGrid[x][y] == 1) && ((aliveNeighbours ==2) || (aliveNeighbours ==3))))
                                future[x][y] = 1;
            
                            else if ((inputGrid[x][y] == 1) && (aliveNeighbours > 3))
                                future[x][y] = 0;
            
                            else if ((inputGrid[x][y] == 0) && (aliveNeighbours == 3))
                                future[x][y] = 1;
            
                            else
                                future[x][y] = inputGrid[x][y];
                        }
                    }
                    return future;
                }
            public static void main(String[] args) {
                    int[][] game = 
                           {{0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
                            {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}
                    };
            
                    System.out.println(nextGeneration(game));
                }

My result is :

    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    };

But the expected result should be:

    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 1}

Cell 10*10 in my result should be alive not dead



Solution 1:[1]

One of the major flaws with your loops is that Java arrays (like most) have a zero-based index. However, your loops start with x and y set to 1, so you are not processing the first row at all. Additionally, your loop conditions stop before you process the last row. This code corrects that error:

public static int[][] nextGeneration(int inputGrid[][]) {
    int height = 10, width = 10;
    int[][] future = new int[height][width];

    // iterate over each row (start with 0 because an array index is 0 based)
    for (int x = 0; x < height; x++) {
        // iterate over each column (start with 0 as well)
        for (int y = 0; y < width; y++) {
            int aliveNeighbours = 0;
            int rowAbove = Math.max(x -1, 0); // the row above is x-1 but never less than 0 because that row doesn't exist
            int rowBelow = Math.min(x + 1, height - 1); // the row below is never greater than the last row in the array (height - 1)
            int colLeft = Math.max(y -1, 0); // go to the left one column, unless we are at the edge, then don't go past 0
            int colRight = Math.min(y + 1, width - 1); // ... continuing the same logic as above
            for (int rowToCheck = rowAbove; rowToCheck <= rowBelow; rowToCheck++)
                for (int colToCheck = colLeft; colToCheck <= colRight; colToCheck++)
                    aliveNeighbours += inputGrid[rowToCheck][colToCheck];

            // remove the cell being evaluated from the neighbors count
            aliveNeighbours -= inputGrid[x][y];

            // simplified logic to remove unnecessary conditions
            // any cell with three neighbors is alive (past value doesn't matter)
            if (aliveNeighbours == 3)
                future[x][y] = 1;
            // any cell with fewer than two live neighbors is dead (past value doesn't matter)
            else if (aliveNeighbours < 2)
                future[x][y] = 0;
            // any cell with more than three neighbors is dead (past value doesn't matter)
            else if (aliveNeighbours >= 4)
                future[x][y] = 0;
            // any cell with two neighbors remains in its present state (regardless of what the past value was)
            else if (aliveNeighbours == 2)
                future[x][y] = inputGrid[x][y];
            else
                throw new RuntimeException("Unhandled neighbor condition");
        }
    }
    return future;
}

public static void main(String[] args) {
    int[][] game =
            {{0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
            {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}
            };

    var nextGen = nextGeneration(game);

    for(var row : nextGen)
    {
        for(var cell : row)
        {
            System.out.print(cell);
        }
        System.out.println();
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Glenn