3

I am a beginner at Java programming (1st semester) and I have been writing code for the Game of Life. I am counting the surrounding cells of each cell in a two-dimensional array. I have reached the point where the program compiles well, but when I test it with different sizes of the array, I can see that the count of the cells is not correct, although the consequent swapping of the cells' status is performed correctly, and I cannot figure out how this can be. Please help:

public static void surrounding(boolean[][] around) {
    for (int i = 0;  i < around.length; i++)
        for (int j = 0; j < around[i].length; j++) {
            int minRow = i == 0 ? i : i - 1;
            int maxRow = i == (around[i].length - 1) ? around[i].length - 1 : i + 1;
            int minCol = j == 0 ? j : j - 1;
            int maxCol = j == (around[i].length - 1) ? around[i].length - 1 : j + 1;
            int count = 0;
            for (int a = minRow; a <= maxRow; a++)
                for (int b = minCol; b <= maxCol; b++) {
                    if ((around[a][b]) && !(a == i && b == j)) 
                        count++;                      

                }
            System.out.print(count + " ");

            if ((around [i][j]) && (count < 2 || count > 3))
                around[i][j] = false;
            else if (!(around[i][j]) && (count == 3))
                around[i][j] = true;

        }
    System.out.println();
    for (int row = 0; row < around.length; row++) {
        for(int column = 0; column < around[row].length; column++) {
            if (around[row][column])
              System.out.print("X ");
            else
              System.out.print(". ");
        }
        System.out.println();
    }
}

And here is the whole program so far:

public static void main(String[] args) {

    boolean[][] world = randomBools(3);
    for (int row = 0; row < world.length; row++) {
        for(int column = 0; column < world[row].length; column++) {
            if (world[row][column])
              System.out.print("X ");
            else
              System.out.print(". ");
        }
        System.out.println();
    }

    System.out.println();
    surrounding(world);

}

public static boolean[][] randomBools(int len) {
    Random random = new Random();
    boolean[][] arr = new boolean[len][len];
    for(int i = 0; i < len; i++)
        for(int j = 0; j < arr[i].length; j++)
          arr[i][j] = random.nextBoolean();

    return arr;
}

public static void surrounding(boolean[][] around) {
    for (int i = 0;  i < around.length; i++)
        for (int j = 0; j < around[i].length; j++) {
            int minRow = i == 0 ? i : i - 1;
            int maxRow = i == (around[i].length - 1) ? around[i].length - 1 : i + 1;
            int minCol = j == 0 ? j : j - 1;
            int maxCol = j == (around[i].length - 1) ? around[i].length - 1 : j + 1;
            int count = 0;
            for (int a = minRow; a <= maxRow; a++)
                for (int b = minCol; b <= maxCol; b++) {
                    if ((around[a][b]) && !(a == i && b == j)) 
                        count++;                      

                }
            System.out.print(count + " ");

            if ((around [i][j]) && (count < 2 || count > 3))
                around[i][j] = false;
            else if (!(around[i][j]) && (count == 3))
                around[i][j] = true;

        }
    System.out.println();
    for (int row = 0; row < around.length; row++) {
        for(int column = 0; column < around[row].length; column++) {
            if (around[row][column])
              System.out.print("X ");
            else
              System.out.print(". ");
        }
        System.out.println();
    }
}

}

RedDree
  • 369
  • 7
  • 18
  • 1
    You are updating 'around' inside the loop, which some cells will be influenced by the "future" value of some of its neighbors. Shouldn't you put these values in a separate matrix and copy them to around after the loops are finished? – goedson Oct 27 '16 at 00:18
  • I see what you mean! :) It seems that was the problem. Going to try and follow your advice. thank you. – RedDree Nov 06 '16 at 13:55
  • Thanks a lot for pointing this out. I have been able to do it the way you suggest, and it works now. – RedDree Nov 06 '16 at 15:41

2 Answers2

2

You use

int minRow = i == 0 ? i : i - 1;
int maxRow = i == (around[i].length - 1) ? around[i].length - 1 : i + 1;
int minCol = j == 0 ? j : j - 1; 
int maxCol = j == (around[i].length - 1) ? around[i].length - 1 : j + 1; 

,but it has to be

int minRow= Math.max(0,i-1);
int maxRow= Math.min(around.length-1,i+1);
int minCol= Math.max(0,j-1);
int maxCol = Math.min(around[i].length-1,j+1);

Since around is a n*n matrix with equaly long side you can use

int maxCol=Math.min(around.length-1,j+1);

Also you can put maxRow and minRow one for loop higher( the loop with i as counter) since maxRow and minRow don't change for the same i.

Roman Gräf
  • 239
  • 2
  • 8
  • Thank you, I'm trying to understand what makes the difference in result. – RedDree Oct 23 '16 at 20:16
  • And no, I cannot initialize the variables a loop higher, because i and j are declared in the loop with I as counter for the first time. – RedDree Oct 23 '16 at 20:19
1
for (int a = minRow; a <= maxRow; a++)
            for (int b = minCol; b <= maxCol; b++) {
                if ((around[a][b]) && !(a == i && b == j)) 
                    count++;                      
            }
        System.out.print(count + " ");

You count the current cell too. you should change this to:

if(a!=0&&b!=0) count++;
Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51