如何简化这种计算细胞邻居数量的生命游戏方法?

How to simplify this Game of Life method that counts the number of neighbors a cell has?

此方法检查单元格是否为边缘单元格(在边界上),然后计算它有多少活邻居。然后返回该值并用于确定该细胞是存活还是死亡。这需要很多 space 并且看起来很丑陋。有没有一种方法可以用更少的行数完成所有这些工作?

// takes in board and checks a cell's neighbors, returning the number of living neighbors
// checks if a cell is on a border, therefore causing it to have less neigbors
public static int checkNeighbors(int[][] board, int i, int j)
{
    int count = 0;   // live neighbors of cell will be added here

    if(i - 1 < 0 && j - 1 < 0)   // in top left corner, only three neighbors
    {
        if(board[i][j + 1] == 1)
            count++;
        if(board[i + 1][j] == 1)
            count++;
        if(board[i + 1][j + 1] == 1)
            count++;
    }
    else if(i - 1 < 0 && j + 1 > width - 1)   // in top right corner, only three neighbors
    {
        if(board[i][j - 1] == 1)
            count++;
        if(board[i + 1][j] == 1)
            count++;
        if(board[i + 1][j - 1] == 1)
            count++;
    }
    else if(i + 1 > height - 1 && j - 1 < 0)   // in bottom left corner, only three neighbors
    {
        if(board[i][j + 1] == 1)
            count++;
        if(board[i - 1][j] == 1)
            count++;
        if(board[i - 1][j + 1] == 1)
            count++;
    }
    else if(i + 1 > height - 1 && j + 1 > width - 1)   // in bottom right corner, only three neighbors
    {
        if(board[i][j - 1] == 1)
            count++;
        if(board[i - 1][j] == 1)
            count++;
        if(board[i - 1][j - 1] == 1)
            count++;
    }
    else if(j - 1 < 0)   // on left border, only five neighbors
    {
        if(board[i - 1][j] == 1)
            count++;
        if(board[i - 1][j + 1] == 1)
            count++;
        if(board[i][j + 1] == 1)
            count++;
        if(board[i + 1][j + 1] == 1)
            count++;
        if(board[i + 1][j] == 1)
            count++;
    }
    else if(j + 1 > width - 1)   // on right border, only five neighbors
    {
        if(board[i - 1][j] == 1)
            count++;
        if(board[i - 1][j - 1] == 1)
            count++;
        if(board[i][j - 1] == 1)
            count++;
        if(board[i + 1][j - 1] == 1)
            count++;
        if(board[i + 1][j] == 1)
            count++;
    }
    else if(i - 1 < 0)   // on top border, only five neighbors
    {
        if(board[i][j - 1] == 1)
            count++;
        if(board[i - 1][j - 1] == 1)
            count++;
        if(board[i - 1][j] == 1)
            count++;
        if(board[i - 1][j + 1] == 1)
            count++;
        if(board[i][j + 1] == 1)
            count++;
    }
    else if(i + 1 > height - 1)   // on bottom border, only five neighbors
    {
        if(board[i][j - 1] == 1)
            count++;
        if(board[i + 1][j - 1] == 1)
            count++;
        if(board[i + 1][j] == 1)
            count++;
        if(board[i + 1][j + 1] == 1)
            count++;
        if(board[i][j + 1] == 1)
            count++;
    }
    else   // cell is not on any border, has full eight neighbors
    {
        if(board[i - 1][j - 1] == 1)
            count++;
        if(board[i - 1][j] == 1)
            count++;
        if(board[i - 1][j + 1] == 1)
            count++;
        if(board[i][j - 1] == 1)
            count++;
        if(board[i][j + 1] == 1)
            count++;
        if(board[i + 1][j - 1] == 1)
            count++;
        if(board[i + 1][j] == 1)
            count++;
        if(board[i + 1][j + 1] == 1)
            count++;
    }
    return count;
}

Whosebug 告诉我添加更多详细信息,因为我的 post 主要是代码。我认为不需要更多详细信息,所以我在此处输入此内容只是为了消除该错误。

这个呢?

for (int y = i-1; y <= i+1; i1++){//loop around point on outer array (y-axis on classic 2D coordinate system)
    for (int x = j-1; x <= j+1; x++) {//loop around point on inner array (x-axis on classic 2D coordinate system)
        if (i==y&&j==x) {
            continue;//same case-->skip
        }
        //option 1
        if(y<0||y>board.length||x<0||x>board[x].length){
            continue;//outside-->skip
        }
        //option 2
//      int otherCellX=y%board.length;//if > length -->start again on other side
//      int otherCellY=x%board[0].length;
//      if (y<0) {//if < 0-->go to end
//          otherCellX+=board.length;
//      }
//      if (x<0) {
//          otherCellY+=board[otherCellX].length;
//      }
        if (board[otherCellX][otherCellY]==1) {//if alive, increment count
            count++;
        }
    }
}

这将遍历当前单元格周围的点。

测试是同一个电芯还是电路板外的电芯。如果不是并且细胞是活的,它会将计数加 1。

选项2中,如果是在板外,则取另一边的数字。

您可以将支票移到一个地方:

public static int countNeighbours(int[][] board, int i, int j) {
    int count = 0;
    for (int x = -1; x <= 1; x++) {
        for (int y = -1; y <= 1; y++) {
            if ((x != 0 || y != 0) && checkCell(board, i + x, j + y)) {
                ++count;
            }
        }
    }
    return count;
}

public static boolean checkCell(int[][] board,int x, int y) {
    return (x >= 0 && y >= 0 && x < width && y < height && board[x][y] == 1);
}

您可以使用 Streams 做一些更短的事情,但如果您不熟悉它们,这会更清楚。

检查索引是否超出范围或等于您的 i,j 参数,如果是则跳过它们。否则,将它们添加到您的 counter.

public static int checkNeighbors(int[][] board, int i, int j) {
    int counter = 0;
    for (int row = i - 1; row <= i + 1; row++) {
        if (row < 0 || row >= board.length) {
            continue;
        }
        for (int column = j - 1; column <= j + 1; column++) {
            if (column < 0 || column >= board[row].length || (row == i && column == j)) {
                continue;
            }
            counter += board[row][column];
        }
    }
    return counter;
}