意想不到的结果c++

Unexpected result C++

本文关键字:c++ 结果 意想不到      更新时间:2023-10-16

我正在制作一款扫雷游戏。然而,在测试生成函数时,它几乎总是发生故障(如果不是总是),我不明白为什么。

下面是我的代码:
#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("nn");
    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),并且所有附近的网格点都是它附近的地雷数量(如果你仍然不熟悉它,这个页面可能会使用)。如你所见,数字4,7和4,4是不正确的。

我不知道为什么会这样。有人能帮助我在这方面的理解,并告诉我如何解决这个问题?


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

Ioums是正确的,在增加单元格之前,您没有检查单元格是否为地雷。但是,根据当前代码的设置方式,这将意味着在每个if语句中添加一个单元格不等于-1的检查。您应该考虑创建一个函数来安全地增加单元格,如果它在边界内而不是地雷,就像这样:

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]++;
    }
}

这意味着你可以用:

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);

在我看来这更容易读懂。此外,由于如果单元格是mine,则该函数不会增加单元格,因此您还可以用以下代码替换if语句!

for(int a=-1; a<=1; a++)
{
    for(int b=-1; b<=1; b++)
    {
        safeIncrement(i+a,j+b, board1);
    }
}

当2个地雷靠近时,问题就发生了:当你在增加地雷数量时,你不会检查那个方块是否有地雷。

假设你在(0,0)上有一个地雷,在(0,1)上有另一个地雷。当你在(0,0)附近增加地雷计数时,你意外地也增加了(0,1)上的地雷计数,将其从-1更改为0。它还使第二个正在处理的矿消失。

我建议使用另一个数字来表示地雷,如-999,并在寻找它们时检查数字是否为负。这比在已有的所有if子句中添加另一个条件要容易。