Lunch
Lunch

Reputation: 57

GameOfLife IndexOutOfBounds Error-handling

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

Answers (3)

Syjin
Syjin

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

under_the_sea_salad
under_the_sea_salad

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.

EDIT

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

Vimal Bera
Vimal Bera

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

Related Questions