Minesweeper
algorithm
puzzle-solving
computer science
game strategy

Minesweeper solving algorithm

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A good Minesweeper solver is not just a brute-force search over all hidden squares. The practical approach combines deterministic rules, local constraint solving, and a probability-based fallback when logic alone cannot prove the next move. That makes Minesweeper a useful algorithm problem because it blends exact deduction with uncertainty management.

Model the Board as Constraints

Each revealed numbered cell creates a constraint. If a cell shows 3, then exactly three of its hidden neighbors must be mines.

For example, suppose a revealed cell has three hidden neighbors and shows 3. Then all three hidden cells must be mines. If it shows 0, then all hidden neighbors are safe.

This gives the two fundamental deterministic rules:

  • if remaining_mines == number_of_hidden_neighbors, all hidden neighbors are mines
  • if remaining_mines == 0, all hidden neighbors are safe

Those rules are enough to solve easy boards and to bootstrap more advanced reasoning.

A Simple Deterministic Solver

A solver can scan all revealed number cells repeatedly until no new information appears.

python
1from collections import defaultdict
2
3
4def neighbors(r, c, rows, cols):
5    for nr in range(max(0, r - 1), min(rows, r + 2)):
6        for nc in range(max(0, c - 1), min(cols, c + 2)):
7            if (nr, nc) != (r, c):
8                yield nr, nc
9
10
11def deterministic_step(board, state):
12    rows, cols = len(board), len(board[0])
13    safe = set()
14    mines = set()
15
16    for r in range(rows):
17        for c in range(cols):
18            if not isinstance(board[r][c], int):
19                continue
20
21            hidden = []
22            flagged = 0
23            for nr, nc in neighbors(r, c, rows, cols):
24                if state[nr][nc] == "hidden":
25                    hidden.append((nr, nc))
26                elif state[nr][nc] == "mine":
27                    flagged += 1
28
29            remaining = board[r][c] - flagged
30            if remaining == 0:
31                safe.update(hidden)
32            elif remaining == len(hidden):
33                mines.update(hidden)
34
35    return safe, mines

Here board stores revealed numbers, while state tracks whether each cell is hidden, known safe, or known mine.

Subset Reasoning Improves the Solver

Deterministic single-cell rules are not enough for medium boards. The next step is to compare constraints.

If one constraint's hidden-neighbor set is a subset of another, the difference between the two sets creates a new rule. For example:

  • set A = x, y contains 1 mine
  • set B = x, y, z contains 2 mines

Then z must be a mine, because B needs one more mine than A and the only extra cell is z.

This subset logic is the basis of many strong human-style solvers. It is still exact reasoning, not guessing.

When Guessing Becomes Necessary

Classic Minesweeper often reaches positions where several mine placements satisfy all local constraints. At that point, no deterministic algorithm can prove a safe move without looking at multiple candidate worlds.

A practical solver then:

  1. builds the frontier of hidden cells touching revealed numbers
  2. enumerates or samples mine assignments consistent with the constraints
  3. estimates the mine probability for each hidden frontier cell
  4. picks the lowest-risk move

This can be done exactly on small frontiers or approximately with random sampling on larger ones.

Why Full Brute Force Is Too Expensive

If there are n unknown cells, naive brute force considers 2^n mine assignments. That is not realistic for larger boards.

The standard optimization is to focus only on the constrained frontier. Hidden cells far away from revealed numbers do not affect local equations yet, so you treat them separately.

That turns an impossible global search into a much smaller frontier search plus a probability estimate for the unexplored area.

Common Pitfalls

  • Treating Minesweeper as pure brute force instead of starting with deterministic constraints.
  • Forgetting to subtract already flagged mines from a clue before reasoning about hidden neighbors.
  • Recomputing the whole board inefficiently without tracking whether new information was added.
  • Guessing too early instead of applying subset reasoning first.
  • Confusing a heuristic probability estimate with a logical proof of safety.

Summary

  • Minesweeper can be modeled as a constraint-solving problem.
  • The first two deterministic rules come from matching clue values against hidden-neighbor counts.
  • Subset reasoning solves many positions that simple rules miss.
  • Guessing is sometimes unavoidable, but it should come after exact logic.
  • Strong solvers combine deterministic deduction with local probability analysis on the frontier.

Course illustration
Course illustration

All Rights Reserved.