GameOfLife IndexOutOfBounds错误处理

时间:2013-12-05 05:51:13

标签: java error-handling

所以,我正在进行一项任务,让一个班级接收为Conway的Game Of Life设置的文本文件。我已经写了所有内容,但是因为我糟糕的错误处理而难以测试。我已经阅读了关于try,catch,throw等的java教程页面。我不明白它,如果我能为IndexOutOfBounds错误做些工作,它会节省很多时间。

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);
}

第一种情况,位于2d数组的边缘将产生第一个错误。我想如果我把代码检查相邻的数组索引...说实话我只是把代码扔在一起就像在黑暗中拍摄一样。如果我能得到一个类似于我的问题的例子,那么举例说明处理一个IndexOutOfBounds错误,我会非常感激。

3 个答案:

答案 0 :(得分:2)

从try-catch场景中取出8 if个语句,而不是关注board的索引是否正确。换句话说,在访问board[Row - 1][Column - 1]之前,请检查0 <= Row-1 <= NumOfRows0 <= Column-1 <= NumOfColumns

修改

更明确的观点。

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

答案 1 :(得分:1)

您正在尝试访问引发board[Row + 1][Column + 1]例外的ArrayIndexOutOfBound

类似board[Row][Column + 1]board[Row + 1][Column]会抛出异常。因为位置Row + 1Column + 1的元素未初始化。

答案 2 :(得分:0)

关于这一个的一些想法...

首先,您使用

访问错误的数组元素
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++;
        }
        ...
    }
}

像这样,你总是检查相同的元素(最后一行,最后一列)。但是你想检查当前元素旁边的元素。像

这样的东西
// [i][j] -> Current Element
// [i-1][j-1] -> Element on the top left
if (board[i - 1][j - 1] == 'X') { 
    aliveCount++;
}
应该使用

。但是,这可以并且将抛出IndexOutOfBoundsException。因此,您必须检查ij的值是否在正确的范围内。因此,添加检查以确保有效值:

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?
}

但是,此代码在循环中重复8次,难以阅读,难以调试且容易出错。因此最好将其转换为单独的功能。像

这样的东西
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++;
}

另一个注意事项:实际上,如果细胞存在,则不需要任何检查。你知道网格的大小,现在你知道不同的情况:板的中间,第一行,最后一行,第一列,第二列,角元素。因此,您可以单独处理这些案例,而不是遍历整个电路板。但这可能对你的榜样有点过分了。