如何简化这种计算细胞邻居数量的生命游戏方法?
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;
}
此方法检查单元格是否为边缘单元格(在边界上),然后计算它有多少活邻居。然后返回该值并用于确定该细胞是存活还是死亡。这需要很多 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;
}