所以,我正在进行一项任务,让一个班级接收为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错误,我会非常感激。
答案 0 :(得分:2)
从try-catch场景中取出8 if
个语句,而不是关注board
的索引是否正确。换句话说,在访问board[Row - 1][Column - 1]
之前,请检查0 <= Row-1 <= NumOfRows
和0 <= 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 + 1
和Column + 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。因此,您必须检查i
和j
的值是否在正确的范围内。因此,添加检查以确保有效值:
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++;
}
另一个注意事项:实际上,如果细胞存在,则不需要任何检查。你知道网格的大小,现在你知道不同的情况:板的中间,第一行,最后一行,第一列,第二列,角元素。因此,您可以单独处理这些案例,而不是遍历整个电路板。但这可能对你的榜样有点过分了。