Skip to content
Behind the Games

How We Built Minesweeper’s First-Click Guarantee

The first click should never lose. Here is the real technique behind our Minesweeper: deferred mine placement and a crash-proof flood fill.

By The 666 Game Team ·

Minesweeper has a reputation problem, and it is not the one you think. The classic complaint is not that the game is too hard — it is that the first click can end everything. You open a fresh board, tap a square at random because you have no information yet, and a mine detonates instantly. Game over before you made a single real decision. That is not difficulty. That is bad luck standing in for design.

When we built our version of Minesweeper, we decided the first click should never lose. Not sometimes. Never. This post walks through exactly how we made that guarantee work, and a second technique that quietly keeps the board from crashing on large clears. Both are small ideas with outsized effects, and both are worth understanding whether you write code or just want to know what is happening under the hood.

You can try the finished result right here, then read on to see how it behaves the way it does.

Play: Minesweeper Open full game →
Score 0 Best 0

Why the first click is a design problem, not a rules problem

Think about what you actually know at the start of a Minesweeper board. Nothing. Every cell is identical and unrevealed. There is no logic you can apply, no number to read, no safe square you can deduce. Your opening move is pure exploration. So if the rules allow that opening move to hit a mine, the game is punishing you for a decision you were never given enough information to make.

Good puzzle design asks players to fail because they reasoned wrong, not because they arrived. The whole appeal of Minesweeper is the deduction chain that unfolds after the board opens up: this cell shows a 1, that flag must be here, therefore this neighbor is safe. None of that can happen if the game is already over. The first click needs to start the puzzle, so it has to be safe by construction.

The naive approach, and why we skipped it

The obvious way to build Minesweeper is to place all the mines the moment the board is created, before the player touches anything. Pick random cells, mark them as mines, count the neighbors, done. It is simple and it is how a lot of tutorials teach it.

The problem is that this locks in the mine layout before the player has made any move at all. If a mine happens to land on the cell you click first, there is nothing anyone can do — the layout was decided in advance. Some implementations try to patch this by detecting a first-click mine and shuffling that single mine somewhere else. That works, but it is fiddly: you have to recompute neighbor counts, you have to make sure the mine does not move onto the very cell it just left, and you have introduced a special case that runs exactly once per game and is therefore easy to get subtly wrong.

We took a cleaner route. We do not place the mines until we know where the player clicked.

Generate the field after the first click

Here is the core idea. When the board first appears, it holds no mines at all. It is just a grid of empty, unrevealed cells. The mine layout does not exist yet.

The player clicks a cell. Now we generate the minefield — and we generate it with full knowledge of which cell was clicked. We place mines at random across the grid, but we treat the clicked cell and its eight surrounding neighbors as off-limits. Mines are never allowed to land in that nine-cell block. Only after the layout is fixed do we compute the neighbor numbers and reveal the clicked area.

Because the clicked cell is excluded from mine placement, the first click cannot lose. And because its eight neighbors are also excluded, the first click is not just safe — it always opens into a small pocket of zeros and low numbers, giving you an actual foothold to start reasoning from. You never open a board and immediately face a wall of high numbers with nowhere to go.

Excluding the neighbors is the detail people forget. If you exclude only the clicked cell itself, the first click is technically survivable but can still reveal a lonely square hemmed in by mines on every side, which is barely better than losing. Excluding the full 3×3 block guarantees the click cascades into open space, which is what makes the opening feel fair.

Placing the mines without collisions

The placement itself is a small loop. We know how many mines the board needs. We build the set of forbidden cells — the clicked cell plus its neighbors — and then we repeatedly pick a random cell. If that cell is forbidden or already holds a mine, we discard it and pick again. If it is free, we place a mine there and count it. We keep going until every mine is placed.

Once all the mines are down, we make one pass over the grid and give each non-mine cell a number: how many of its up-to-eight neighbors are mines. That number is the entire information system of Minesweeper. Every deduction you make for the rest of the game reads off those counts.

Doing placement this way means the special case disappears. There is no “oops, the first click was a mine, let me shuffle” branch, because a mine on the first click was never possible in the first place. The safety is a property of how the field is built, not a correction applied afterward. Fewer branches means fewer bugs.

The other quiet hero: flood fill with an explicit stack

The first-click guarantee gets you a fair opening. The second technique keeps that opening from crashing the game.

When you reveal a cell that has zero neighboring mines, Minesweeper does not stop there. A zero means all its neighbors are safe too, so the game reveals them automatically. If any of those neighbors is also a zero, the reveal keeps spreading outward until it hits cells that touch mines. That expanding wave is called a flood fill, and it is why one click on an empty region can open up a huge swath of the board in an instant.

The textbook way to write flood fill is recursion: reveal a cell, then call the same function on each neighbor, which calls it on each of their neighbors, and so on. It reads beautifully and it works fine on small boards. But every one of those nested calls sits on the call stack, and the call stack has a limit. On a large board with a big open region, a recursive flood fill can pile up thousands of pending calls and blow past that limit, crashing the whole game right when the player did nothing wrong except click a very empty area.

So we do not use recursion. We use an explicit stack — a plain list of cells waiting to be processed — and a loop.

How the explicit stack works

The logic is straightforward. We start by pushing the clicked cell onto the stack. Then we loop: pop a cell off the stack, reveal it, and if it turned out to be a zero, push each of its unrevealed neighbors onto the stack. Repeat until the stack is empty. When the loop finishes, the entire connected region has been revealed.

This does exactly the same work as the recursive version — it visits the same cells and reveals the same region — but the waiting cells live in a list we control instead of on the language’s call stack. That list can grow as large as it needs to without any risk of overflowing, so a giant clear on a big board is no different from a small one. It just loops a few more times.

There is one small discipline that matters: we mark a cell as revealed before, or right as, we push its neighbors, so the same cell never gets added twice. Skip that and the stack can balloon with duplicates and the loop can revisit cells it already handled. With the guard in place, every cell is processed exactly once and the fill is both fast and safe.

Small techniques, big difference

Neither of these ideas is exotic. Deferring mine placement until the first click is a handful of extra lines. Swapping recursion for an explicit stack is a change of shape, not of logic. But together they decide whether the game feels fair and stays stable, or whether it occasionally punishes you for existing and crashes on a lucky-looking click.

That is the theme behind a lot of what we build: the difference between a good version of a classic and a frustrating one usually is not a grand feature. It is a few careful decisions about the moments players never think about — the very first click, and the very biggest clear.

Curious to feel it in practice? Play the full board over on the Minesweeper game page, and if you want the wider story of how we build things, our post on making games run on a five-year-old phone covers the performance side of the same philosophy.

Frequently asked questions

Can the first click ever hit a mine?
No. We do not place any mines until after you click. The clicked cell is excluded from mine placement, so the first click can never lose.
Why exclude the eight neighbours too, not just the clicked cell?
Excluding the full 3x3 block guarantees the first click opens into a pocket of zeros and low numbers, giving you a real foothold instead of a lonely square boxed in by mines.
How are the mines placed after the first click?
We pick random cells, skip any that are forbidden or already hold a mine, and place mines until the required count is reached, then compute each cell's neighbour number.
What is flood fill in Minesweeper?
When you reveal a cell with zero neighbouring mines, the game automatically reveals its neighbours, and keeps spreading through connected zeros until it reaches numbered cells.
Why use an explicit stack instead of recursion for flood fill?
A recursive fill can pile up thousands of nested calls on a large open board and overflow the call stack, crashing the game. An explicit stack holds the waiting cells in a list we control, so it never overflows.
Does deferring mine placement change the difficulty?
No. The same number of mines is placed across the board; they simply avoid your very first click, which only removes unfair opening losses.

← All posts Play a game