I'm a beginner in coding. I have this problem that I know already, but I can't seem to find the solution
Given a preset 5x5 2D array representing the board (.
means dead cell and 0
means living cell.
)
. . . . .
. . . . .
. . 0 . .
. . . . .
. . . . .
I have a method countLivingNeighbors
that counts the "living" cells around a cell.
When I visualize the number of living neighbors of each cell in a the same grid pattern, the expected output and the actual output are:
EXPECTED: ACTUAL:
0 0 0 0 0 0 0 0 0 0
0 1 1 1 0 0 1 1 1 0
0 1 0 1 0 0 1 0 0 0
0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
I know the problem is that the method countLivingNeighbors
doesn't count a "living" cell if its position is on the left, above-right, above, or above-left of the current cell. But I'm pretty sure the logic of my code is alright, I think.
For reference, here's the code for the method:
// 'true' means living, 'false' means dead
static int countLivingNeighbors(boolean[][] board, int posX, int posY) {
int counter = 0;
// Iterate around the cell
for (int j = -1; j <= 1; j ) {
if (posY j < 0 || posY j >= board.length) continue;
for (int i = -1; i <= 1; i ) {
if (posX i < 0 || posX i >= board[0].length) continue;
if (board[posY j][posX i]) counter;
}
}
// It counts the current cell as well, so let's remove that.
if (board[posY][posX]) --counter;
return counter;
I don't think I have problems with the code except for this which stomps me for quite a while now. Any help is much appreciated.
Here's the current version of the entire code.
package GameOfLife;
import java.util.Random;
public class Main {
public static void main(String[] args){
int boardWidth = 5, boardHeight = 5;
boolean[][] board = {{false, false, false, false, false},
{false, false, false, false, false},
{false, false, true , false, false},
{false, false, false, false, false},
{false, false, false, false, false}};
renderBoard(board);
System.out.println();
board = getNextBoardState(board);
renderBoard(board);
}
static boolean[][] createRandomBoard(int width, int height) {
boolean[][] board = new boolean[height][width];
for (int i = 0; i < height; i ) {
for (int j = 0; j < width; j ) {
switch (new Random().nextInt(2)) {
case 0 -> board[i][j] = false;
case 1 -> board[i][j] = true;
}
}
}
return board;
}
static void renderBoard(boolean[][] board) {
for (boolean[] cellRows : board) {
for (boolean cells : cellRows) {
if (cells) System.out.print(" 0 ");
else System.out.print(" . ");
} System.out.println();
}
}
static boolean[][] getNextBoardState(boolean[][] board) {
boolean[][] nextBoard;
nextBoard = board;
for (int y = 0; y < board.length; y ) {
for (int x = 0; x < board[0].length; x ) {
int livingNeighbors = countLivingNeighbors(board, x, y);
System.out.print(" " livingNeighbors " ");
nextBoard[y][x] = setNextCellState(livingNeighbors, board[y][x]);
} System.out.println();
} System.out.println();
return nextBoard;
}
static int countLivingNeighbors(boolean[][] board, int posX, int posY) {
int counter = 0;
for (int j = -1; j < 2; j ) {
if (posY j < 0 || posY j >= board.length) continue;
for (int i = -1; i < 2; i ) {
if (posX i < 0 || posX i >= board[0].length) continue;
if (board[posY j][posX i]) counter;
}
}
if (board[posY][posX]) --counter;
return counter;
}
static boolean setNextCellState(int livingNeighbors, boolean cellState) {
if (cellState) {
if (livingNeighbors <= 1 || livingNeighbors > 3) return false;
} else {
if (livingNeighbors == 3) return true;
}
return cellState;
}
}
CodePudding user response:
In the getNextBoardState
method you are assigning nextBoard = board
.
static boolean[][] getNextBoardState(boolean[][] board) {
boolean[][] nextBoard;
nextBoard = board;
It's natural to think that this should copy all of the values in the board
array into a new array called nextBoard
. But in fact, it creates a new pointer called nextBoard
, which points to the same array as board
. This means that when you change a value in nextBoard
, you are in fact changing the same value pointed to by board
.
To get around this, make a method that copies values from the board into a new board. Here's a very simple example (which has some pitfalls of its own):
private static boolean[][] copyBoard(boolean[][] board) {
boolean[][] newBoard = new boolean[board.length][board[0].length];
for (int i = 0; i < board.length; i ) {
for (int j = 0; j < board[i].length; j ) {
newBoard[i][j] = board[i][j];
}
}
return newBoard;
}
Then in getNextBoardState
, replace
boolean[][] nextBoard;
nextBoard = board;
with
boolean[][] nextBoard = copyBoard(board);
You should get the result you expect:
0 0 0 0 0
0 1 1 1 0
0 1 0 1 0
0 1 1 1 0
0 0 0 0 0
Note: the copyBoard
method assumes that board
always has at least one inner array (board[0]
) and that all of board
's inner arrays have the same length as the array at board[0]
.