扫雷码错误

时间:2015-01-22 16:38:49

标签: c++

#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
int n,m,counter=0;;
cin>>n>>m;
char x[n][m];
int y[n][m];
for(int i=0;i<n;i++)
{
    for(int j=0;j<m;j++)
    {
        cin>>x[i][j];              //array input
    }
}
for(int i=0;i<n;i++)
{
    for(int j=0;j<m;j++)
    {
        counter=0;
        if(x[i][j]=='.')                         // searching for mines(*)
        {
            if (x[i][j-1]=='*')
                counter++;
            if (x[i][j+1]=='*')
                counter++;
            if (x[i-1][j]=='*')
                counter++;
            if (x[i+1][j]=='*')
                counter++;
            if (x[i+1][j-1]=='*')
                counter++;
            if (x[i+1][j+1]=='*')
                counter++;
            if (x[i-1][j-1]=='*')
                counter++;
            if (x[i-1][j+1]=='*')
                counter++;
        }
        if(x[i][j]!='*')
        y[i][j]=counter;                  // assign values
        else
        y[i][j]='*';

    }
}
for(int i=0;i<n;i++)
{
    for(int j=0;j<m;j++)
    {
        if(y[i][j]==42)
            cout<<'*';
        else
        cout<<y[i][j];                // output numeric array 
    }
    cout<<endl;
}
    return 0;
}

这是Minesweeper代码,其输入类似于

4 4
*...
....
.*..
....

和输出

*100
2210
1*10
1110

但是代码的输出是

*101
2210
1*10
1110

右上角的零变成1是什么让它做到了?

是否有更简单的方法来搜索没有所有if条件的地雷(*)?

2 个答案:

答案 0 :(得分:1)

你正在读取数组的内存。当你在第0..n-2行时,你正在阅读下一行的字符,在n-1行,你正在读取无法访问的内存。

您必须检查您访问的内存是否属于正确的行并且在数组范围内。

       if (x[i][j+1]=='*')

如果j == m - 1怎么办?

       if (x[i-1][j]=='*')

如果i == 0怎么办?

这个问题基本上有两个修复。 首先,您可以每次检查i, j是否在界限内,比如说

       if (j < m - 1 && x[i][j+1]=='*')

这将解决问题,但从代码重用的角度来看是不好的。我写了一个函数,比如说

char get_at(char ** array, int i, int j, int n, int m)
{
   if (i >= 0 && i < n && j >= 0 && j < m)
      return array[i][j];
   else
      return '!';
}

如果索引超出界限,此函数将返回'!',因此不会将其解释为我的。

答案 1 :(得分:0)

我想在你的代码中指出一些事情:

int main()
{
int n,m,counter=0;;
cin>>n>>m;
char x[n][m];
int y[n][m];

/** 
  * Minesweeper solving has always worked (if followed step-wise) is        
  * scanning the neihbouring 8 cells i.e.    
  * top(left,middle,right),side(left,right), and 
  * bottom(left,middle,right). You probably should try and follow this
  * in your code so that any indexing issues can be avoided
  *
  *
  * BTW - don't forget the corners/edges
  *
  */
for(int i=0;i<n;i++) // This is a bit dangerous what if the index is -1?
{
    for(int j=0;j<m;j++) // Same indexing issue here.
    {
        cin>>x[i][j];
    }
}
for(int i=0;i<n;i++)
{
    for(int j=0;j<m;j++) 
    {
        counter=0;
        if(x[i][j]=='.') // If current pos is '.'
        {
            if (x[i][j-1]=='*')
                counter++;
            if (x[i][j+1]=='*')
                counter++;
            if (x[i-1][j]=='*')
                counter++;
            if (x[i+1][j]=='*')
                counter++;
            if (x[i+1][j-1]=='*')
                counter++;
            if (x[i+1][j+1]=='*')
                counter++;
            if (x[i-1][j-1]=='*')
                counter++;
            if (x[i-1][j+1]=='*')
                counter++;
        }
        if(x[i][j]!='*') // If current pos is ANYTHING but '*', may be you want ELSE_IF condition?
        y[i][j]=counter;
        else
        y[i][j]='*';

    }
}
for(int i=0;i<n;i++)
{
    for(int j=0;j<m;j++)
    {
        if(y[i][j]==42)
            cout<<'*';
        else
        cout<<y[i][j];
    }
    cout<<endl;
}
    return 0;
}

这是你在想什么?