Search code examples
c++minesweeper

Unexpected result C++


I am creating a Minesweeper game. However, while testing the generating function, It malfunctions almost always (if not always), and I do not understand why.

Here is my code:

#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("\n\n");
    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;
}

This produces:

-   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

As you most likely already know, in the game of minesweeper, there is mines (in this case will they will be marked as X), and all nearby grid points are the number of mines near it (if you are still unfamiliar with it this page may of use). As you can see, the numbers at 4,7 and 4,4 are incorrect.

I do not know why this is this way. Could someone aid my understanding in this, and tell my how to to fix this?


Also, I just noticed that this produces the same output every time it is run. Why?


Solution

  • Ioums is correct, you are not checking to see if a cell is a mine before incrementing it. However, with the way that your code is currently set up, this will mean adding a check that the cell does not equal -1 in every single if statement. You should consider creating a function to safely increment a cell if it is within bounds and not a mine, like so:

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

    This means that you can replace your if statements with:

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

    Which is much more readable in my opinion. Additionally, since the function doesn't increment the cell if it is a mine, you could also replace the if statements with the following code!

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