我正在尝试编写一个程序,在20x60单元格的网格上实现Conway的生命游戏。网格应环绕,使左侧连接到右侧,顶部连接到底部。
因此,任何位置为(0, col)
的单元格都会在(maxRow, col)
处有一个邻居。位置为(row, 0)
的任何单元格都会在(row, maxCol)
处有一个邻居。
以下函数用于计算相邻单元格的数量。它适用于不在边缘的坐标,但不适用于那些坐标。例如,如果(0, 10)
处有点,(0, 11)
,(0, 12)
和(0, 10)
被传递到函数中,它将返回一个高数字作为邻居计数而不是{ {1}}。我知道mod运算符1
会有所帮助,但我不明白如何使用它。
%
答案 0 :(得分:1)
在提供解决方案之前,让我先做一些观察。
添加一些网格值并稍后减去其他网格值不是一个好主意。您应该首先计算正确的网格坐标。
当您编写count += grid[i][j];
时,您正在使用可能无效的数组索引。例如,当i = row - 1
为零时,row
会产生i
-1
的值。
您的代码暗示maxrow
是行数,因为您正在编写maxrow-1
,但名称maxrow
表示最大行索引。这令人困惑。调用行数numRows
会更好,然后最大的行索引是numRows - 1
。同样,最好将maxcol
替换为numCols
。
现在到了问题的核心。值row - 1
可以等于-1
,row + 1
可以等于numRows
。这两个都是无效的行索引。同样,col - 1
和col + 1
可能会导致无效的列索引-1
和numCols
。解决问题的一种方法是测试这些特定值并用环绕索引替换它们:
int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
int R = i;
if (R == -1) {
R = numRows - 1;
} else if (R == numRows) {
R = 0;
}
for (int j = col - 1; j <= col + 1; j++) {
if (i == row && j == col) {
continue; // Skip grid[row][col].
}
int C = j;
if (C == -1) {
C = numCols - 1;
} else if (C == numCols) {
C = 0;
}
count += grid[R][C];
}
}
这是一种解决问题的高性能方法,因为测试和分配比模数更快的操作,但它也是很多代码。我们可以在模运算符的帮助下编写更简洁的代码。
我们想写i % numRows
,但是当i
为-1时,C ++会将其计算为-1。这是因为模数运算对于负值是模糊的而C++ has chosen an interpretation不能保证非负结果。
要解决此问题,我们在使用模numRows
之前将i
添加到numRows
。这可以确保我们始终采用正数的模数。现在我们可以计算grid[row][col]
的八个邻居中的活细胞数量,如下所示。
int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
for (int j = col - 1; j <= col + 1; j++) {
if (i == row && j == col) {
continue; // Skip grid[row][col].
}
count += grid[(i + numRows) % numRows][(j + numCols) % numCols];
}
}