目前,我正在尝试检查网格单元格中的所有单元格中的数据。向上,向左,向下,向右和所有对角线。如何使用异常抛出,因此我不必单独编码边和角?
这是我现在所拥有的。 isIsAlive()只是检查单元格是否“活动”。一个细胞的邻居包括它周围的所有活跃细胞。
public void calcNeighbors() throws ArrayIndexOutOfBoundsException{
int x =0;
int y =0;
int neighbors = 0;
while(x < 9){
while(y < 9){
if(generation[x+1][y+1].isIsAlive()){
neighbors++;
}
if(generation[x+1][y].isIsAlive()){
neighbors++;
}
if(generation[x+1][y-1].isIsAlive()){
neighbors++;
}
if(generation[x][y-1].isIsAlive()){
neighbors++;
}
if(generation[x-1][y-1].isIsAlive()){
neighbors++;
}
if(generation[x-1][y].isIsAlive()){
neighbors++;
}
if(generation[x-1][y+1].isIsAlive()){
neighbors++;
}
if(generation[x][y+1].isIsAlive()){
neighbors++;
}
y++;
}
x++;
neighbors = 0;
}
}
答案 0 :(得分:4)
你的if块列表是丑陋的(直言不讳)而且很危险。而是使用嵌套for循环,但计算考虑边缘的for循环的上限和下限。
for (int x = 0; x < MAX_X; x++) {
for (int y = 0; y < MAX_Y; y++) {
int minRow = Math.max(0, x - 1);
int maxRow = Math.min(MAX_X - 1, x + 1);
int minCol = Math.max(0, y - 1);
int maxCol = Math.min(MAX_Y - 1, y + 1);
for (int row = minRow; row <= maxRow; row++) {
for (int col = minCol; col <= maxCol; col++) {
if (row != x || col != y) {
if(generation[row][col].isIsAlive()){
neighbors[x, y]++;
}
}
}
}
}
}
答案 1 :(得分:3)
如果假设的邻居超出界限,你不应该抛出自己的异常。无论如何,Java都会抛出ArrayIndexOutOfBoundsException
。
在访问阵列之前,您需要检查边界;如果x
或y
超出范围,请勿访问该数组。
答案 2 :(得分:1)
不建议为此目的使用例外。但如果你坚持,你可以通过以下方式做到。首先,定义一个方法
public boolean isAlive(int x,int y) {
try {
return this.generation[x][y].isIsAlive() ;
} catch(IndexOutOfBoundsException ex) {
return false ; // Or whatever you want to be the default
}
}
然后使用isAlive(x+1,y+1)
代替generation[x+1][y+1].isIsAlive()
等等。
此外,我的印象是你错误地声明了一个局部变量int neighbors = 0;
。我之所以这样说,是因为你最后将它设置为0
,但你不会将它存储在任何地方。就个人而言,我会在neighbors
的基类中定义一个字段generation
,并且:
for(int x= 0 ; x < generation.length ; x++ ) {
for(int y= 0 ; y < generation[x].length ; y++ ) {
generation[x][y].neighbors= 0 ;
for(int dx= -1 ; dx <= 1 ; dx++ ) {
for(int dy= -1 ; dy <= 1 ; dy++ ) {
if( ! ( dx == 0 && dy == 0 ) && isAlive(x+dx,y+dx) ) {
generation[x][y].neighbors++;
}
}
}
}
我对这么多if
的关注是3:
1.犯错很容易。
2.在所有if
内添加任何其他代码将是耗时的(并且容易出错)。
3.逻辑更容易理解。虽然您也可以添加一条注释,说明您要检查邻居,并且邻居都是8个单元格,其中行或列是+1或-1当前单元格。
此外,既然我们已经减少了if
的数量,我们也可以内联上面的函数并写下以下内容:
for(int x= 0 ; x < generation.length ; x++ ) {
for(int y= 0 ; y < generation[x].length ; y++ ) {
generation[x][y].neighbors= 0 ;
for(int dx= -1 ; dx <= 1 ; dx++ ) {
for(int dy= -1 ; dy <= 1 ; dy++ ) {
try {
if( ! ( dx == 0 && dy == 0 ) && isAlive(x+dx,y+dx) ) {
generation[x][y].neighbors++;
}
} catch(IndexOutOfBoundsException ex) {
// Do whatever you want in this case
}
}
}
}
}
现在,没有滥用异常(这是目前推荐的最多),我想说添加一个功能
public boolean isValidNeighbor(int i,int j) {
return 0 <= i && i < generation.length && 0 <= j && j < generation[i].length ;
}
您的代码变为:
for(int x= 0 ; x < generation.length ; x++ ) {
for(int y= 0 ; y < generation[x].length ; y++ ) {
generation[x][y].neighbors= 0 ;
for(int dx= -1 ; dx <= 1 ; dx++ ) {
for(int dy= -1 ; dy <= 1 ; dy++ ) {
if( ! ( dx == 0 && dy == 0 ) && isValidNeighbor(x+dx,y+dx) && isAlive(x+dx,y+dx) ) {
generation[x][y].neighbors++;
}
}
}
}
}
好多了。而且,即使不是主要原因,代码和复杂性也少于异常!!!