意外的结果C ++

时间:2015-10-26 18:46:57

标签: c++ minesweeper

我正在创造一个扫雷游戏。但是,在测试生成功能时,它几乎总是发生故障(如果不是总是),我不明白为什么。

这是我的代码:

#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处的数字不正确。

我不知道为什么会这样。有人可以帮助我理解这一点,并告诉我如何解决这个问题吗?

另外,我注意到每次运行时都会产生相同的输出。为什么呢?

2 个答案:

答案 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,并在查找时查看号码是否为负数。这比为你已经拥有的所有条款添加另一个条件容易。