简体   繁体   中英

Minesweeper Program, unexpected output

I was doing one problem(Minesweeper) from Steven Skiena(Programming Challenges). Where you have to output the number of mines adjacent to that square.

#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>m>>n;
char a[m][n];
for(int i=0;i<m;i++)
{
    for (int j = 0; j < n; j++)
    {
        cin>>a[i][j];
    }
}

for (int i = 0; i < m; i++)
{
    for (int j = 0; j < n; j++)
    {
        if(a[i][j]!='*')
        {
            int no=0;
            if(a[i-1][j-1]=='*')
            no++;
            else if(a[i][j-1]=='*')
            no++;
            else if(a[i+1][j-1]=='*')
            no++;
            else if(a[i+1][j]=='*')
            no++;
            else if(a[i+1][j+1]=='*')
            no++;
            else if(a[i][j+1]=='*')
            no++;
            else if(a[i-1][j+1]=='*')
            no++;
            else if(a[i-1][j]=='*')
            no++;
            a[i][j]=(char)no;
        }
    }

}


for(int i=0;i<m;i++)
{
    for (int j=0; j<n; j++)
    {
        cout<<a[i][j];
    }
    cout<<endl;
}


return 0;
}

When I try to run this program, the array where the mines isn't placed are blank. Is it something related to the casting of integer to character?

One mistake is this:

a[i][j]=(char)no;

This is not the way you convert a one-digit integer into the char representation.

The correct way is to add '0' to the integer:

a[i][j] = no + '0';

The reason why this works is that the character representation of the number is different than the actual digit value. For example, the ASCII collating sequence uses 48 as the character '0' , 49 for '1' , 50 for '2' , etc.

Thus adding '0' , ie 48, will give you the character representation of the number.

You could change your program for example like this:

I changed your array to an int-array and all mines are a -1 . So you don't have to mix int-values and char-values in one array. With this you have to handle this in the output with an if-condition.

#include<iostream>
using namespace std;

int main()
{
    int n,m;
    cin>>m>>n;
    char a[m][n];

    for(int i=0;i<m;i++)
    {
        for (int j = 0; j < n; j++)
        {
            char in;
            cin>>in;
            if(in == '*') {
                a[i][j] = -1;
            } else {
                a[i][j] = 0;
            }
        }
    }

    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if(a[i][j]!=-1)
            {
                int no=0;
                if(a[i-1][j-1]==-1)
                no++;
                else if(a[i][j-1]==-1)
                no++;
                else if(a[i+1][j-1]==-1)
                no++;
                else if(a[i+1][j]==-1)
                no++;
                else if(a[i+1][j+1]==-1)
                no++;
                else if(a[i][j+1]==-1)
                no++;
                else if(a[i-1][j+1]==-1)
                no++;
                else if(a[i-1][j]==-1)
                no++;
                a[i][j]=no;
            }
        }

    }


    for(int i=0;i<m;i++)
    {
        for (int j=0; j<n; j++)
        {
            if(a[i][j] == -1) {
                cout<<" * ";
            } else {
                cout<<" "<<a[i][j]<<" ";
            }
        }
        cout<<endl;
    }

    return 0;
}

Since it looks like people are giving men fish, i don't see a reason not to. Change the line of how no starts for a nice solution computationally.

    char no='0';

I see a few separate issues here that, collectively, are leading to the issue you're running into.

First, as pointed out above, once you've counted the number of mines adjacent to each mine, you're currently storing the result in a way that won't print the way you expect it to. The other answers here have suggested several different ways that you can do this.

Second, your way of counting adjacent mines is (slightly) incorrect. Let's look at this code:

if(a[i-1][j-1]==-1)
   no++;
else if(a[i][j-1]==-1)
   no++;
else if(a[i+1][j-1]==-1)
   no++;
else if(a[i+1][j]==-1)
   no++;
else if(a[i+1][j+1]==-1)
   no++;
else if(a[i][j+1]==-1)
   no++;
else if(a[i-1][j+1]==-1)
   no++;
else if(a[i-1][j]==-1)
   no++;

The pattern here you're using of if / else if / else if /... means that at most one of these branches will execute. That is, as soon as this code finds a mine, it stops looking at the other locations around the cell for other mines. One way to fix this is to make this not a chain of if / else if , but just a regular chain of if s:

if(a[i-1][j-1]==-1)
   no++;
if(a[i][j-1]==-1)
   no++;
if(a[i+1][j-1]==-1)
   no++;
if(a[i+1][j]==-1)
   no++;
if(a[i+1][j+1]==-1)
   no++;
if(a[i][j+1]==-1)
   no++;
if(a[i-1][j+1]==-1)
   no++;
if(a[i-1][j]==-1)
   no++;

You may even want to consider changing how you've structured this so that, instead of having a long list of if statements, you use a doubly-nested for loop to enumerate all positions one step away from you. that will condense the code and make it more clearly match the pattern of "for each adjacent location, if it's a mine, count it as such."

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM