使用2D矢量创建简单的扫雷应用程序

时间:2017-04-30 06:41:27

标签: c++ vector minesweeper 2d-vector

我正在尝试使用2D矢量构建一个简单的扫雷应用程序。首先,我用1和0填充正方形(1' s表示地雷,0' s表示清楚)。

srand(time(NULL));
for (int i = 0; i < battlefield.size(); i++)
{
    for (int j = 0; j < battlefield[i].size(); j++)
    {
        int num = (rand() % 2);
        battlefield[i][j] = num;
    }
}`

然后,我再次检查向量并计算周围地雷的数量。这就是我遇到问题的地方。我想当它试图检查一个超出界限的广场时,它会爆炸。但是,如果在任何这些检查之前失败。如果在尝试查看当前方块是否等于1时失败。

for (int i = 0; i < battlefield.size(); i++)
{
    for (int j = 0; j < battlefield[i].size(); j++)
    {
        int count = 0;
        if (battlefield[i][j] == 1)//mine square
        {
            if (battlefield[i - 1][j - 1] != 0)
            {
                count++;
            }
            if (battlefield[i][j - 1] != 0)
            {
                count++;
            }
            if (battlefield[i + 1][j - 1] != 0)
            {
                count++;
            }
            if (battlefield[i - 1][j] != 0)
            {
                count++;
            }
            if (battlefield[i + 1][j] != 0)
            {
                count++;
            }
            if (battlefield[i - 1][j + 1] != 0)
            {
                count++;
            }
            if (battlefield[i][j + 1] != 0)
            {
                count++;
            }
            if (battlefield[i + 1][j + 1] != 0)
            {
                count++;
            }
            battlefield[i][j] = count;
        }
    }

我不确定为什么会失败,有什么想法?

3 个答案:

答案 0 :(得分:1)

制作“CheckTile”功能

bool CheckTile(int i, int j)
{
    // check if both i and j are in the map bounds, return false if not
    if(i < 0 || i >= battlefield.size() || j < 0 || j >= battlefield.size()) 
        return false;

    // return true if the tile is a mine, false if not
    return (battlefield[i - 1][j - 1] != 0);
}

基本上用CheckTile调用替换所有if检查的内部。您当前的代码是破坏的,因为您没有对数组进行边界检查,所以当它读取时

if(battlefield[i - 1][j - 1] != 0)

第一次,它试图读取分配内存之外的数组位置(-1,-1),因此出错。用

替换它
if(CheckTile(i - 1, j - 1))

它会做同样的事情,但是增加了边界检查保护。

答案 1 :(得分:1)

如果你的我的是0,0你执行的第一次检查将检查-1,-1这是超出范围,实际上炸毁了你的程序。

您需要先检查边界。

答案 2 :(得分:1)

你真的很幸运。访问std::vector的边界是“未定义的行为”,只有幸运时程序才会停止。

当你运气不好的时候,程序显然“正常工作”而且你一直在添加功能,直到发货日......在股东大会期间它只会在客户机器的宽屏幕上爆炸: - )

在我看来,更简单的实现将是

int i0 = std::max(0, i-1), i1 = std::min(height-1, i+1);
int j0 = std::max(0, j-1); j1 = std::min(width-1, j+1);
int count = 0;
for (int i=i0; i<=i1; i++) {
    for (int j=j0; j<=j1; j++) {
        if (mine[i][j]) count++;
    }
}

基本上首先计算安全边界然后在其中循环,而不是单独指定代码中的所有邻居。