Search code examples
c++multidimensional-arrayminesweeper

Recursively mapping mines on a minesweeper board


I have been trying to make a minesweeper game where given coordinates for a cell it will recursively reveal adjacent cells until a cell adjacent to a bomb is found. I have a method that given coordinates x and y calculates how many mines are surrounding it.

// Counts how many mines are adjacent to a given coordinate cell if any
void board::mineCount(int x, int y) {

// North
if (y > 0) {
    if (board[x][y - 1].hasMine) {
        board[x][y].mineCount++;
    }
}

// South
if (y < dimensions[1] - 1) {
    if (board[x][y + 1].hasMine) {
        board[x][y].mineCount++;

    }
}

// East
if (x < dimensions[0] - 1) {
    if (board[x + 1][y].hasMine) {
        board[x][y].mineCount++;

    }
}

// West
if (x > 0) {
    if (board[x - 1][y].hasMine) {
        board[x][y].mineCount++;
    }
}

// North East
if (x < dimensions[0] - 1 && y > 0) {
    if (board[x + 1][y - 1].hasMine) {
        board[x][y].mineCount++;

    }
 }

// North West
if (x > 0 && y > 0) {
    if (board[x - 1][y - 1].hasMine) {
        board[x][y].mineCount++;
    }
}

// South East
if (x < dimensions[0] - 1 && y < dimensions[1] - 1) {
    if (board[x + 1][y + 1].hasMine) {
        board[x][y].mineCount++;

    }
}

// South West
if (x > 0 && y < dimensions[1] - 1) {
    if (board[x - 1][y + 1].hasMine) {
        board[x][y].mineCount++;
    }
  }
}

Each cell is a struct which has a mineCount field that gets incremented by 1 each time a mine is found adjacent to it. I am having trouble figuring out where my recursion logic would go. I tried doing something like:

// North
if (y > 0) {
    if (board[x][y - 1].hasMine) {
        board[x][y].mineCount++;
    } else {
        minecount(x, y-1);
    }
}

for each position but to no avail. Any pointers would be appreciated.


Solution

  • The recursion shouldn't be a part of the code that performs the mine count itself. It should be part of the function that's responsible for revealing nearby tiles.

    int get_adjacent_mine_count(point p) {
        int mine_count = 0;
        for(int i = -1; i <= 1; i++) {
            for(int j = -1; j <= 1; j++) {
                point this_point(p.x + i, p.y + j);
                //is_inside_board checks to see if the point's coordinates are less than 0 
                //or greater than the board size
                if(!is_inside_board(board, this_point)) continue; 
                //We ignore the center tile
                if(i == 0 && j == 0) continue;
    
                if(board(this_point).hasMine) 
                    mine_count++;
            }
        }
        return mine_count;
    }
    
    void reveal_tiles(point p) {
        //We shouldn't throw if the recursion is correct
        if(board(p).hasMine) throw Explosion("Stepped on a Mine!");
        //Single call to previously defined function
        int num_of_adjacent_mines = get_adjacent_mine_count(p);
        //I'm assuming this gets initialized to -1 beforehand
        board(p).revealed = num_of_adjacent_mines; 
        if(num_of_adjacent_mines == 0) {
            for(int i = -1; i <= 1; i++) {
                for(int j = -1; j <= 1; j++) {
                    point this_point(p.x + i, p.y + j);
                    if(!is_inside_board(board, this_point)) continue;
                    if(i == 0 && j == 0) continue;
                    if(board(this_point).revealed == -1) 
                        reveal_tiles(this_point);
                }
            }
        }
    }
    

    I'm going to strongly recommend you write a simple Matrix class to represent board, which my code implies you've done, because that's a much more robust solution than just trying to interact with a 2D array the C-style way you're doing it.