# Minesweeper Solver

• Difficulty Level : Hard
• Last Updated : 28 Sep, 2021

Given a 2D array arr[][] of dimensions N*M, representing a minesweeper matrix, where each cell contains an integer from the range [0, 9], representing the number of mines in itself and all the eight cells adjacent to it, the task is to solve the minesweeper and uncover all the mines in the matrix. Print ‘X’ for the cell containing a mine and ‘_’ for all the other empty cells. If it is not possible to solve the minesweeper, then print “-1”.

Examples:

Input:
arr[][] = {{1, 1, 0, 0, 1, 1, 1},
{2, 3, 2, 1, 1, 2, 2},
{3, 5, 3, 2, 1, 2, 2},
{3, 6, 5, 3, 0, 2, 2},
{2, 4, 3, 2, 0, 1, 1},
{2, 3, 3, 2, 1, 2, 1},
{1, 1, 1, 1, 1, 1, 0}}.
Output:
_ _ _ _ _ _ _
x _ _ _ _ x _
_ x x _ _ _ x
x _ x _ _ _ _
_ x x _ _ _ x
_ _ _ _ _ _ _
_ x _ _ x _ _

Input:
arr[][] = {{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 1, 1},
{0, 0, 1, 1, 1, 1, 1},
{0, 0, 2, 2, 2, 0, 0},
{0, 0, 2, 2, 2, 0, 0},
{0, 0, 1, 1, 1, 0, 0}}
Output:
_ _ _ _ _ _ _
_ _ _ _ _ _ _
_ _ _ _ _ _ x
_ _ _ _ _ _ _
_ _ _ x _ _ _
_ _ _ x _ _ _
_ _ _ _ _ _ _

Input Generation: To solve the given minesweeper matrix arr[][], it must be a valid input i.e., the minesweeper matrix must be solvable. Therefore, the input matrix is generated in generateMineField() function. Follow the below steps to generate the input minesweeper matrix:

• The inputs for the generation of input are the size of the minefield N and M and also probability P (or density) of the minefield.
• A probability P is equal to 0 if there are no mines in the minefield and P is equal to 100 if all the cells are mines in the minefield.
• A random number is chosen for each cell and if the random number is less than P, a mine is assigned to the grid and a boolean array mines[][] is generated.
• The input to the constraint solver is the status of each grid which counts the mines of itself and the eight cells around it.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Stores the number of rows``// and columns of the matrix``int` `N, M;` `// Stores the final generated input``int` `arr;` `// Direction arrays``int` `dx = { -1, 0, 1, -1, 0, 1, -1, 0, 1 };``int` `dy = { 0, 0, 0, -1, -1, -1, 1, 1, 1 };` `// Function to check if the``// cell location is valid``bool` `isValid(``int` `x, ``int` `y)``{``    ``// Returns true if valid``    ``return` `(x >= 0 && y >= 0``            ``&& x < N && y < M);``}` `// Function to generate a valid minesweeper``// matrix of size ROW * COL with P being``// the probability of a cell being a mine``void` `generateMineField(``int` `ROW, ``int` `COL, ``int` `P)``{``    ``// Generates the random``    ``// number every time``    ``srand``(``time``(NULL));` `    ``int` `rand_val;` `    ``// Stores whether a cell``    ``// contains a mine or not``    ``int` `mines[ROW][COL];` `    ``// Iterate through each cell``    ``// of the matrix mine``    ``for` `(``int` `x = 0; x < ROW; x++) {``        ``for` `(``int` `y = 0; y < COL; y++) {``            ``// Generate a random value``            ``// from the range [0, 100]``            ``rand_val = ``rand``() % 100;` `            ``// If rand_val is less than P``            ``if` `(rand_val < P)` `                ``// MArk mines[x][y] as True``                ``mines[x][y] = ``true``;` `            ``// Otherwise, mark``            ``// mines[x][y] as False``            ``else``                ``mines[x][y] = ``false``;``        ``}``    ``}` `    ``cout << ``"Generated Input:\n"``;` `    ``// Iterate through each cell (x, y)``    ``for` `(``int` `x = 0; x < ROW; x++) {``        ``for` `(``int` `y = 0; y < COL; y++) {``            ``arr[x][y] = 0;` `            ``// Count the number of mines``            ``// around the cell (x, y)``            ``// and store in arr[x][y]``            ``for` `(``int` `k = 0; k < 9; k++) {``                ``// If current adjacent cell is valid``                ``if` `(isValid(x + dx[k], y + dy[k])``                    ``&& (mines[x + dx[k]][y + dy[k]]))``                    ``arr[x][y]++;``            ``}` `            ``// Print the value at``            ``// the current cell``            ``cout << arr[x][y] << ``" "``;``        ``}``        ``cout << endl;``    ``}``}` `// Driver Code``int` `main()``{``    ``N = 7, M = 7;``    ``int` `P = 20;` `    ``// Function call to generate``    ``// a valid minesweeper matrix``    ``generateMineField(N, M, 15);``}`
Output:
```Generated Input:
0 1 1 1 1 1 1
1 3 3 3 2 2 1
1 2 2 2 2 2 1
1 2 2 2 1 1 0
1 2 1 1 1 1 1
1 3 2 2 1 1 1
1 3 2 2 1 1 1```

Approach: The given problem can be solved using Backtracking. The idea is to iterate over each cell of a matrix, based on the information available from the neighboring cells, assign a mine to that cell or not.

Follow the below steps to solve the given problem:

• Initialize a matrix, say grid[][], and visited[][] to store the resultant grid and keep the track of visited cells while traversing the grid. Initialize all grid values as false.
• Declare a recursive function solveMineSweeper() to accept arrays arr[][], grid[][], and visited[][] as a parameter.
• If all the cells are visited and a mine is assigned to the cells satisfying the given input grid[][], then return true for the current recursive call.
• If all the cells are visited but the solution is not satisfying the input grid[], return false for the current recursive call.
• If the above two conditions are found to be false, then find an unvisited cell (x, y) and mark (x, y) as visited.
• If a mine can be assigned to the position (x, y), then perform the following steps:
• Mark grid[x][y] as true.
• Decrease the number of mine of the neighboring cells of (x, y) in the matrix arr[][] by 1.
• Recursively call for solveMineSweeper() with (x, y) having a mine and if it returns true, then a solution exists. Return true for the current recursive call.
• Otherwise, reset the position (x, y) i.e., mark grid[x][y] as false and increase the number of mines of the neighboring cells of (x, y) in the matrix arr[][] by 1.
• If the function solveMineSweeper() with (x, y) having no mine, returns true, then it means a solution exists. Return true from the current recursive call.
• If the recursive call in the above step returns false, that means the solution doesn’t exist. Therefore, return false from the current recursive calls.
• If the value returned by the function solveMineSweeper(grid, arr, visited) is true, then a solution exists. Print the matrix grid[][] as the required solution. Otherwise, print “-1”.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Stores the number of rows``// and columns in given matrix``int` `N, M;` `// Maximum number of rows``// and columns possible``#define MAXM 100``#define MAXN 100` `// Directional Arrays``int` `dx = { -1, 0, 1, -1, 0, 1, -1, 0, 1 };``int` `dy = { 0, 0, 0, -1, -1, -1, 1, 1, 1 };` `// Function to check if the``// cell (x, y) is valid or not``bool` `isValid(``int` `x, ``int` `y)``{``    ``return` `(x >= 0 && y >= 0``            ``&& x < N && y < M);``}` `// Function to print the matrix grid[][]``void` `printGrid(``bool` `grid[MAXN][MAXM])``{``    ``for` `(``int` `row = 0; row < N; row++) {``        ``for` `(``int` `col = 0; col < M; col++) {``            ``if` `(grid[row][col])``                ``cout << ``"x "``;``            ``else``                ``cout << ``"_ "``;``        ``}``        ``cout << endl;``    ``}``}` `// Function to check if the cell (x, y)``// is valid to have a mine or not``bool` `isSafe(``int` `arr[MAXN][MAXM], ``int` `x, ``int` `y)``{` `    ``// Check if the cell (x, y) is a``    ``// valid cell or not``    ``if` `(!isValid(x, y))``        ``return` `false``;` `    ``// Check if any of the neighbouring cell``    ``// of (x, y) supports (x, y) to have a mine``    ``for` `(``int` `i = 0; i < 9; i++) {` `        ``if` `(isValid(x + dx[i], y + dy[i])``            ``&& (arr[x + dx[i]][y + dy[i]] - 1 < 0))``            ``return` `(``false``);``    ``}` `    ``// If (x, y) is valid to have a mine``    ``for` `(``int` `i = 0; i < 9; i++) {``        ``if` `(isValid(x + dx[i], y + dy[i]))` `            ``// Reduce count of mines in``            ``// the neighboring cells``            ``arr[x + dx[i]][y + dy[i]]--;``    ``}` `    ``return` `true``;``}` `// Function to check if there``// exists any unvisited cell or not``bool` `findUnvisited(``bool` `visited[MAXN][MAXM],``                   ``int``& x, ``int``& y)``{``    ``for` `(x = 0; x < N; x++)``        ``for` `(y = 0; y < M; y++)``            ``if` `(!visited[x][y])``                ``return` `(``true``);``    ``return` `(``false``);``}` `// Function to check if all the cells``// are visited or not and the input array``// is satisfied with the mine assignments``bool` `isDone(``int` `arr[MAXN][MAXM],``            ``bool` `visited[MAXN][MAXM])``{``    ``bool` `done = ``true``;``    ``for` `(``int` `i = 0; i < N; i++) {``        ``for` `(``int` `j = 0; j < M; j++) {``            ``done``                ``= done && (arr[i][j] == 0)``                  ``&& visited[i][j];``        ``}``    ``}` `    ``return` `(done);``}` `// Function to solve the minesweeper matrix``bool` `SolveMinesweeper(``bool` `grid[MAXN][MAXM],``                      ``int` `arr[MAXN][MAXM],``                      ``bool` `visited[MAXN][MAXM])``{` `    ``// Function call to check if each cell``    ``// is visited and the solved grid is``    ``// satisfying the given input matrix``    ``bool` `done = isDone(arr, visited);` `    ``// If the solution exists and``    ``// and all cells are visited``    ``if` `(done)``        ``return` `true``;` `    ``int` `x, y;` `    ``// Function call to check if all``    ``// the cells are visited or not``    ``if` `(!findUnvisited(visited, x, y))``        ``return` `false``;` `    ``// Mark cell (x, y) as visited``    ``visited[x][y] = ``true``;` `    ``// Function call to check if it is``    ``// safe to assign a mine at (x, y)``    ``if` `(isSafe(arr, x, y)) {` `        ``// Mark the position with a mine``        ``grid[x][y] = ``true``;` `        ``// Recursive call with (x, y) having a mine``        ``if` `(SolveMinesweeper(grid, arr, visited))` `            ``// If solution exists, then return true``            ``return` `true``;` `        ``// Reset the position x, y``        ``grid[x][y] = ``false``;``        ``for` `(``int` `i = 0; i < 9; i++) {``            ``if` `(isValid(x + dx[i], y + dy[i]))``                ``arr[x + dx[i]][y + dy[i]]++;``        ``}``    ``}` `    ``// Recursive call without (x, y) having a mine``    ``if` `(SolveMinesweeper(grid, arr, visited))` `        ``// If solution exists then return true``        ``return` `true``;` `    ``// Mark the position as unvisited again``    ``visited[x][y] = ``false``;` `    ``// If no solution exists``    ``return` `false``;``}` `void` `minesweeperOperations(``int` `arr[MAXN][MAXN], ``int` `N,``                           ``int` `M)``{` `    ``// Stores the final result``    ``bool` `grid[MAXN][MAXM];` `    ``// Stores whether the position``    ``// (x, y) is visited or not``    ``bool` `visited[MAXN][MAXM];` `    ``// Initialize grid[][] and``    ``// visited[][] to false``    ``memset``(grid, ``false``, ``sizeof``(grid));``    ``memset``(visited, ``false``, ``sizeof``(visited));` `    ``// If the solution to the input``    ``// minesweeper matrix exists``    ``if` `(SolveMinesweeper(grid, arr, visited)) {` `        ``// Function call to print the grid[][]``        ``printGrid(grid);``    ``}` `    ``// No solution exists``    ``else``        ``printf``(``"No solution exists\n"``);``}` `// Driver Code``int` `main()``{``    ``// Given input``    ``N = 7;``    ``M = 7;``    ``int` `arr[MAXN][MAXN] = {``        ``{ 1, 1, 0, 0, 1, 1, 1 },``        ``{ 2, 3, 2, 1, 1, 2, 2 },``        ``{ 3, 5, 3, 2, 1, 2, 2 },``        ``{ 3, 6, 5, 3, 0, 2, 2 },``        ``{ 2, 4, 3, 2, 0, 1, 1 },``        ``{ 2, 3, 3, 2, 1, 2, 1 },``        ``{ 1, 1, 1, 1, 1, 1, 0 }``    ``};` `    ``// Function call to perform``    ``// generate and solve a minesweeper``    ``minesweeperOperations(arr, N, M);` `    ``return` `0;``}`
Output:
```_ _ _ _ _ _ _
x _ _ _ _ x _
_ x x _ _ _ x
x _ x _ _ _ _
_ x x _ _ _ x
_ _ _ _ _ _ _
_ x _ _ x _ _```

Time Complexity: O(2N * M * N * M)
Auxiliary Space: O(N * M)

My Personal Notes arrow_drop_up