Reputation: 57
So, I'm working on an assignment to make a class to receive text files set up for Conway's Game Of Life. I have written everything, but its hard to test since I suck as error-handling. I have read the java tutorial pages on try, catch, throw, etc. I don't understand it, and it would save me a lot of time if I could get something working for IndexOutOfBounds errors.
public void computeNextGeneration(int generation) {
int aliveCount;
tempBoard = new char[Column][Row];
int generationCount = 1;
System.out.print("Generation" + generationCount);
print();
do {
for (int i = 0; i < Row; i++) {
for (int j = 0; j < Column; j++) {
aliveCount = 0;
try {
if (board[Row - 1][Column - 1] == 'X') {
aliveCount++;
}
if (board[Row - 1][Column] == 'X') {
aliveCount++;
}
if (board[Row - 1][Column + 1] == 'X') {
aliveCount++;
}
if (board[Row][Column - 1] == 'X') {
aliveCount++;
}
if (board[Row][Column + 1] == 'X') {
aliveCount++;
}
if (board[Row + 1][Column - 1] == 'X') {
aliveCount++;
}
if (board[Row + 1][Column + 1] == 'X') {
aliveCount++;
}
if (board[Row + 1][Column + 1] == 'X') {
aliveCount++;
}
if (board[i][j] == 'X') {
if (aliveCount < 2) {
setCell(j, i, 0);
}
if (aliveCount > 2) {
setCell(j, i, 0);
} else {
setCell(j, i, 1);
}
}
if (board[i][j] == '0') {
if (aliveCount == 3) {
setCell(j, i, 1);
}
}
} catch (IndexOutOfBoundsException e) {
}
throw new IndexOutOfBoundsException();
}
board = tempBoard;
generationCount++;
System.out.print("Generation" + generationCount);
print();
System.out.println();
generation--;
}
} while (generation > 1);
}
The very first case, being on the edge of the 2d array will give the first error. I thought if I put the code that checks neighboring array indices... to be honest I was just throwing code together like shots in the dark. If I could get an example similar to my problem, anything that exemplifies handling an IndexOutOfBounds error, I would really appreciate it.
Upvotes: 2
Views: 118
Reputation: 2810
A few thoughts about this one...
First, you are accessing the wrong array elements with
for (int i = 0; i < Row; i++) {
for (int j = 0; j < Column; j++) {
...
// Wrong Indices, possible Exception
// vvvvvvv vvvvvvvvvvv
if (board[Row - 1][Column - 1] == 'X') {
aliveCount++;
}
...
}
}
Like this, you are always checking the same element (last row, last column). But you want to check the element next to the current element. So something like
// [i][j] -> Current Element
// [i-1][j-1] -> Element on the top left
if (board[i - 1][j - 1] == 'X') {
aliveCount++;
}
should be used. However, this can and will throw an IndexOutOfBoundsException. So you have to check if the values of i
and j
are in the correct Range. So add checks to ensure valid values:
if (0 <= (i - 1) && (i - 1) <= Row && 0 <= (j - 1) && (j - 1) <= Column) {
if (board[i - 1][j - 1] == 'X') {
aliveCount++;
}
} else {
// TODO: What to do with the Edges? Assume 0/1? Wrap around?
}
However, this code is repeated 8 times in your loop, which will be hard to read, hard to debug and error prone. So it is better to move this into a seperate function. Something like
public boolean cellIsAlive(char[][] board, int row, int col)
{
if (0 <= (row - 1) && (row - 1) <= Row && 0 <= (col- 1) && (col- 1) <= Column) {
if (board[row - 1][col- 1] == 'X') {
return true;
}
} else {
// TODO: What to do with the Edges? Assume 0/1? Wrap around?
return false;
}
return false;
}
...
if (cellIsAlive(board, i, j)) {
aliveCount++;
}
Another note: Actually you don't need any of the checks if the cells exist. You know the size of the grid and you now the different cases: Middle of the board, first row, last row, first column, second column, corner elements. So instead of looping through the whole board, you can treat these cases seperately. But that might be overkill for your example.
Upvotes: 0
Reputation: 1834
Take the 8 if
statements out of the try-catch scenario and instead focus on checking whether or not the indices for board
are correct. In other words, before accessing board[Row - 1][Column - 1]
, check that 0 <= Row-1 <= NumOfRows
and 0 <= Column-1 <= NumOfColumns
.
More explicit view.
for (int i = 0; i < NumOfRows; i++) {
for (int j = 0; j < NumOfColumns; j++) {
aliveCount = 0;
if (i-1 >= 0 && i-1 <= NumOfRows) {//This case checks the cell to the left
aliveCount++;
}
//Other cases
Upvotes: 2
Reputation: 10497
You are trying to accessing board[Row + 1][Column + 1]
which throws ArrayIndexOutOfBound
exception.
Similary board[Row][Column + 1]
and board[Row + 1][Column]
throws an exception. Because elements at position Row + 1
and Column + 1
are not initialized.
Upvotes: 1