我正试图用c ++制作生活游戏,这是我有史以来的第一次C ++练习。我有一个问题,我们需要制作一些游戏模式,比如一个被称为“圆环”的游戏模式,其中离开棋盘的单元格应该在另一侧重新进入。
现在,我正在检查邻居。但我正在用很多if条款对它进行硬编码,因为我尝试了一些for循环,但它没有用。
但这真的是唯一的选择吗?硬编码每种可能性(左侧,右侧,上侧,下侧等的单元?
这是我的代码片段:
$Users = User::all();
foreach ($Users as $User) {
foreach ($userIDs as $user_id) {
if ($user_id == $User->id) {
echo '<br/>';
echo $user_id;
$User->has_rotas = 1;
} else {
$User->has_rotas = 0;
}
}
$User->save();
}
}
我写的一个for循环,但没有真正起作用,是以下 - 循环计数过多的单元格。在循环之后,所有细胞总是处于死亡状态,因为程序总是计数超过3个活细胞,即使从一开始只有2个细胞存活。我希望这个解释很有帮助,有点难以解释。我做了一个外印 - “+” - 它通常显示大约5/6加号,即使它只应显示两次(两个活细胞)。
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;
有没有可以简化的选项?比如循环,就像我试过的那样?或者这是应该做的方式?我现在真的没有看到隧道尽头的光。只是为了让我知道我是否一无所获。我真的遇到了一些C ++语法的问题,因为到目前为止我只用了大约一年的Java,所以我是C ++的初学者。我很感激任何提示!
答案 0 :(得分:5)
是。使用模数运算符:
而不是
if (board[a + 1][b + 1] != DEAD) {
使用:
if (board[(a + 1) % HEIGHT][(b + 1) % WIDTH] != DEAD) {
进行减法时有一点点复杂性(%
实际上不是模数运算,它是余数运算)。你不想在-1上使用它(它只会返回-1),所以添加一个额外的HEIGHT / WIDTH:
if (board[(a - 1 + HEIGHT) % HEIGHT][(b - 1 + WIDTH) % WIDTH] != DEAD) {
然后,您可以对电路板的所有单元使用相同的代码。
答案 1 :(得分:1)
此行尝试访问不在矩阵范围内的矩阵元素:
if (board[a + c][b + d] != DEAD) {
在执行此行之前,您必须检查a + c
和b + d
是否在矩阵范围内,如果它们不是应该执行的操作。对于“圆环”要求,我猜“左”和“右”超出范围应该用换行值替换,并且应该跳过超出范围的“顶部”和“底部”。
答案 2 :(得分:1)
除了Martin Bonner's answer之外,准备八个邻居的抵消表:
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++;
}
}