Search code examples
c++minesweeper

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?


Solution

  • 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 ifs:

    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!