生活的游戏邻居检查(更简单的方法可能吗?)
Game of Life Neighbour Check (easier method possible?)
我现在正试图用c++制作生活游戏,这是我有史以来的第一次c++练习。我有一个问题,我们需要制作一些游戏模式,比如一种被称为"圆环"的游戏模式,离开棋盘的细胞应该在相反的一侧重新进入棋盘。
现在,我正在检查邻居。但我用大量的if子句对它进行了硬编码,因为我尝试了一些for循环,但没有成功。
但这真的是唯一的选择吗?硬编码每种可能性(左侧、右侧、上侧、下侧等单元格)?
这是我的代码片段:
int countNeighboursTorus(int a, int b) {
int living = 0;
// when the starting cell is the one on the upper left (start of the board)
if (a == 0 && b == 0) {
// cell below
if (board[a - 1][b] != DEAD) {
living++;
}
// cell right below
if (board[a + 1][b + 1] != DEAD) {
living++;
}
// cell right
if (board[a][b + 1] != DEAD) {
living++;
}
// cell above (other side of the board)
if (board[HEIGHT - 1][b] != DEAD) {
living++;
}
// cell above right (other side of the board)
if (board[HEIGHT - 1][b + 1] != DEAD) {
living++;
}
}
// first edge case (height = 0, width != 0):
else if (a == 0 && b != 0) {
// cell below
if (board[a - 1][b] != DEAD) {
living++;
}
// cell right below
if (board[a + 1][b + 1] != DEAD) {
living++;
}
// cell right
if (board[a][b + 1] != DEAD) {
living++;
}
// cell left below
if (board[a + 1][b - 1] != DEAD) {
living++;
}
// cell left
if (board[a][b - 1] != DEAD) {
living++;
}
// cell left above (other side of the board)
if (board[HEIGHT - 1][b - 1] != DEAD) {
living++;
}
// cell above (other side of the board)
if (board[HEIGHT - 1][b] != DEAD) {
living++;
}
// cell above right (other side of the board)
if (board[HEIGHT - 1][b + 1] != DEAD) {
living++;
}
}
return living;
}
我写了一个for循环,但并没有真正起作用,它是如下所示的——这个循环总是计算太多的单元格。循环后,所有细胞总是处于死亡状态,因为程序总是计数3个以上的活细胞,即使从一开始只有2个活细胞。我希望这个解释是有帮助的,它有点难以解释。我做了一个输出——"+"——它通常显示大约5/6个加号,即使它应该只显示两次(两个活细胞)。
// for any other "normal" cases inside of the board:
else if (a != 0 && b != 0 && a < HEIGHT - 1 && b < WIDTH - 1) {
for (int c = -1; c < 2; c++) {
for (int d = -1; d < 2; d++) {
if (!(c == 0 && d == 0)) {
if (board[a + c][b + d] != DEAD) {
living++;
}
}
}
}
}
有没有任何简化的选择?比如循环,就像我试过的那样?还是应该这样做?我现在真的没有看到隧道尽头的曙光。只是为了让我知道我这样做是否是徒劳的。我在C++语法方面确实遇到了一些问题,因为到目前为止我只做了大约一年的Java,所以我是C++的初学者。我很感激你给我的任何提示!
是。使用模数运算符:
代替
if (board[a + 1][b + 1] != DEAD) {
用途:
if (board[(a + 1) % HEIGHT][(b + 1) % WIDTH] != DEAD) {
做减法时会有一点复杂(%
实际上不是模运算,而是余数运算)。你不想在-1上使用它(它只会返回-1),所以添加一个额外的高度/宽度:
if (board[(a - 1 + HEIGHT) % HEIGHT][(b - 1 + WIDTH) % WIDTH] != DEAD) {
然后,您可以对电路板的所有单元使用相同的代码。
此行尝试访问不在矩阵范围内的矩阵元素:
if (board[a + c][b + d] != DEAD) {
在执行这一行之前,您必须检查a + c
和b + d
是否在矩阵范围内,以及它们是否不是应该执行的操作。对于"torus"需求,我认为超出范围的"left"answers"right"应该替换为换行值,超出范围的"top"answers"bottom"应该跳过。
除了Martin Bonner的答案外,还要准备八个邻居的偏移表:
static const int NoOfNeighbors = 8;
int dVertNeigh [NoOfNeighbors] = {
HEIGHT-1, HEIGHT-1, HEIGHT-1,
0, 0,
1, 1, 1};
int dHorizNeigh [NoOfNeighbors] = {
WIDTH-1, 0, 1,
WIDTH-1, 1,
WIDTH-1, 0, 1};
然后你可以用一个简单的循环来计数相邻的细胞:
for (int ngh = 0; ngh < NoOfNeighbors; ngh++) {
int neighborV = (a + dVertNeigh[ngh]) % HEIGHT;
int neighborH = (b + dHorizNeigh[ngh]) % WIDTH;
if (board[neighborV][neighborH] != DEAD) {
living++;
}
}
- 查找定义我的 C/C++ 函数/宏的文件比'grep'更简单的方法
- 让类与运算符一起工作更简单的方法
- 多个 if-else 测试的更简单方法
- 为具有多个参数的函数创建 SWIG 类型图的更简单方法?
- 有没有更简单的方法可以从用户那里获取三个数字并按升序打印它们?
- 约束模板参数顺序的更简单方法
- C++ 将整数与硬编码的整数集进行比较的更简单方法
- 有没有一种方法可以在基于枚举的可变参数模板函数之间进行选择,这比将函数包装在结构中更简单
- 一种在没有 root 的情况下加载共享库的更简单方法
- 是否有一种更简单的方法可以使用GDB将C捕获的C结构捕获
- 生活的游戏邻居检查(更简单的方法可能吗?)
- 有没有更简单的方法可以做到:if(num1 > num2 && num1 > num3),以获得更大的变量列表进行比较?
- 有没有更简单的方法在 Rcpp 中使用 NumericVector 编写条件语句
- 访问派生属性和给定基指针的方法的更简单方法
- 是否有更简单的方法来定义C 中的for循环中的条件
- 格式化为 wstring 更简单的方法
- 我编写了一个C++程序来打印单词字母的排列.我想知道是否有其他更简单的方法可以做到这一点
- 为对象::tr传递QString的更简单方法
- 安全布尔成语 - 我是否找到了更简单的方法,还是我错过了什么
- 实现.cpp文件的更简单方法