我正在创造一个扫雷游戏。但是,在测试生成功能时,它几乎总是发生故障(如果不是总是),我不明白为什么。
这是我的代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
struct board {
int width=9, mines=10;
char board[9][9];
/* char board[][]
* -1 = Mine
* 0 = No mines near
* 0+ = x amount of mines are near
*/
};
struct point {
int x,y;
};
board newBoard(){
board board1;
point randPoint;
for(int i=0;i<board1.width;i++){
for(int j=0;j<board1.width;j++) board1.board[i][j]=0; // Initialize array
}
for(int i=0;i<board1.mines;i++){
randPoint.x=rand()%board1.width, randPoint.y=rand()%board1.width; // Where will the mine go?
if(board1.board[randPoint.x][randPoint.y]!=-1){ // If not already a mine
board1.board[randPoint.x][randPoint.y]=-1; //make a mine
} else i--; //else don't count this
}
for(int i=0;i<board1.width;i++){
for(int j=0;j<board1.width;j++){
if(board1.board[i][j]==-1) { // If mine exists
// The if checks preceding the ++'s are to prevent out of bounds erors
if (j-1>=0) board1.board[i][j-1]++;
if (j+1<board1.width) board1.board[i][j+1]++;
if (i-1>=0) board1.board[i-1][j]++;
if (i+1<board1.width) board1.board[i+1][j]++;
if ((i-1>=0) && (j-1>=0)) board1.board[i-1][j-1]++;
if ((i-1>=0) && (j+1<board1.width))board1.board[i-1][j+1]++;
if ((i+1<board1.width) && (j-1>=0))board1.board[i+1][j-1]++;
if ((i+1<board1.width) && (j+1<board1.width))board1.board[i+1][j+1]++;
}
}
}
return board1;
}
int main() {
board boardGame=newBoard();
printf("- ");
for(int i=0;i<boardGame.width;i++) printf("%i ",i+1);
printf("\n\n");
for(int i=0;i<boardGame.width;i++){
printf("%i. ",i+1);
for(int j=0;j<boardGame.width;j++) if (boardGame.board[i][j]==-1) {
printf(" X");
} else {
printf(" %i", boardGame.board[i][j]);
}
printf("\n");
}
return 0;
}
这会产生:
- 1 2 3 4 5 6 7 8 9
1. 0 0 0 0 1 X 1 0 0
2. 1 1 0 0 2 2 2 1 1
3. X 2 1 1 1 X 1 1 X
4. 1 2 X 0 1 1 0 1 1
5. 0 1 1 1 0 0 0 0 0
6. 0 0 0 0 1 1 1 0 0
7. 0 0 1 1 2 X 1 0 0
8. 1 1 2 X 2 1 1 0 0
9. 1 X 2 1 1 0 0 0 0
你很可能已经知道,在扫雷游戏中,有地雷(在这种情况下它们会标记为X
),所有附近的网格点都是它附近的地雷数量(如果您仍然不熟悉this页面可能会使用)。如您所见,4,7和4,4处的数字不正确。
我不知道为什么会这样。有人可以帮助我理解这一点,并告诉我如何解决这个问题吗?
另外,我注意到每次运行时都会产生相同的输出。为什么呢?
答案 0 :(得分:2)
Ioums是正确的,你没有在增加它之前检查一个单元是否是我的。但是,对于当前设置代码的方式,这将意味着在每个if语句中添加一个单元格不等于-1的检查。你应该考虑创建一个函数来安全地增加一个单元格,如果它在一个边界而不是一个地雷中,如下所示:
ID
这意味着您可以用以下内容替换if语句:
void safeIncrement(int x, int y, board& b)
{
if(x >= 0 && y >= 0 && x < b.width && y < b.width && b.board[x][y] != -1)
{
b.board[x][y]++;
}
}
在我看来哪个更具可读性。另外,由于函数不是增量单元格,如果它是我的,你也可以用下面的代码替换if语句!
safeIncrement(i-1,j,board1);
safeIncrement(i-1,j-1,board1);
safeIncrement(i-1,j+1,board1);
safeIncrement(i,j-1,board1);
safeIncrement(i,j+1,board1);
safeIncrement(i+1,j,board1);
safeIncrement(i+1,j-1,board1);
safeIncrement(i+1,j+1,board1);
答案 1 :(得分:0)
当2个地雷靠近时,就会出现问题:当你增加矿井数量时,你不会检查那个地方是否有地雷。
假设你在(0,0)和(0,1)上获得了一个矿井。当您在矿井数量(0,0)附近添加时,您不小心也会在(0,1)中添加矿井,将其从-1更改为0.这也会使正在处理的第二个矿井消失。
我建议使用另一个号码来表示我的地雷,例如-999,并在查找时查看号码是否为负数。这比为你已经拥有的所有条款添加另一个条件容易。