1

目前,我正在尝试检查网格单元格周围所有单元格中的数据。上、左、下、右和所有对角线。我怎样才能使用异常抛出,所以我不必单独编码边和角?

这是我目前所拥有的。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;
    }
}
4

3 回答 3

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]++;
           }
         }
      }
    }
  }
}
于 2013-08-26T23:46:58.327 回答
3

如果假设的邻居超出范围,您不应该抛出自己的异常。Java无论如何都会抛出一个ArrayIndexOutOfBoundsException

您需要在访问数组之前检查您的界限;如果您的xy超出范围,请勿访问该数组。

于 2013-08-26T23:47:02.257 回答
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在 and 的基类中定义一个字段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++;
              }
        }
    }
}

我对这么多ifs的担心是3:1。很容易出错。if2. 在所有s中添加任何其他代码将很耗时(并且容易出错) 。3.逻辑更容易理解。尽管您也可以添加注释说明您要检查邻居,并且邻居都是 8 个单元格,其中行或列是当前单元格的 +1 或 -1。

此外,既然我们减少了ifs 的数量,我们还可以内联上面的函数并编写以下内容:

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

好多了,好多了。而且,即使不是主要原因,代码和复杂性也比异常少!!!

于 2013-08-26T23:54:03.347 回答