Why Minesweeper is a Perfect Game
I recently became obsessed with progamming the classic puzzle game Minesweeper. I ported it to MetaMask and had so much fun doing it that I made an open source minimalist web implementation too.
After shipping these ports I got addicted to playing it over and over, which is natural. It’s one of the best puzzle games ever made. So I figured I would talk about why it’s perfect and why it’s so fun to program too.
A Hint of Mystery, and Danger…
The initial state of a Minesweeper game is the ultimate Russian Roulette. You have no way of knowing if your first click will lead to an immediate loss. Unlike games like Sudoku, which start with an indication of what you should do next, or Tetris, which starts with a clean slate, Minesweeper starts by forcing you to make the most dangerous move of all: a blind sweep. However, that sweep can be very satisfying if you manage to click a space that is not adjacent to any mines, as it will trigger a cascade of reveals and open up a large space.
From there, you can begin marking spaces that you think have mines and carefully revealing more of the board, but every game will require at least a few blind sweep to reveal enough spaces to proceed. Further, it’s fun when you accidentally lose the game on a blind sweep — each game is quick enough that you can lose and immediately start another game without feeling frustrated.
In terms of gameplay, Minesweeper involves moving from chaos to order. Each board starts with high entropy — a completley random arrangement of hidden mines — and as you play, you attempt to overcome that chaos by carefully sweeping the board. All good puzzle games involve some degree of fighting or managing entropy. For example, in Tetris, you start the game with zero entropy, and as you make choices of where to place tetrominoes, you inadvertently create entropy that you consistently need to eliminate. In Bejeweled, you are constantly battling against entropy — each attempt to eliminate it introduces more entropy as random pieces enter the board again. Minesweeper fits into the category of “entropy reducing” games, like Mahjong Solitaire, where you start with high entropy and attempt to reduce it to zero. To “clear” a board completely is immensely satisfying, and your first win will hook you and make you want to experience it again.
Minesweeper is one of the most ported games in existence, and rightfully so. It’s easy to play, highly accessible, and requires very little computing power to run. Did you know there was a Minesweeper game on the original Game Boy? It was only released in Japan, unfortunately.
Also, if you search Minesweeper on Google, you’ll find a playable Google Doodle… don’t tell your boss though!
Deceptively Easy to Program
I mentioned that Minesweeper is fun to program. The logic is very simple. I will attempt to explain it with pseudocode here, but you can also view the source for my minimalist web implementation if you are comfortable with JavaScript.
The first step is to generate a random board. For an 9x9 board with 10 mines, it’s as simple as making an array of length 81 with 10 1’s and 71 0’s, the shuffling that array to make the placement of mines random. However, if you want to generate all of the spaces with their values (the numbers that show how many mines are adjacent to a space), then you can use the decimal numbers 0–9 in each space of the array:
- 0 = empty space with nothing around it
- 1–8 = empty space with 1 to 8 mines adjacent to it (the max any space can have is 8
- 9 = a space with a mine
After generating a random array to represent the board with 10 9’s and 71 0’s, you can walk the array, find each mine, and add 1 to each space around it that does not have a mine. This will pre-fill the values 1–8 for the adjacent spaces.
Then, you can walk the array again and add 10 to each space. Any value over 10 indicates an unswept space. When sweeping, you subtract 10 and you will have a number 0–9 that indicates if it’s an empty space with or without adjacent mines, or if it has a mine. So a starting board will be an array of length 81 with the numbers 10–19 scattered throughout.
Thus, each time the player sweeps a space, you check if the value is 19, which equals an instant loss, reveal all the spaces that have 19 (to reveal the remaining bombs), and end the game. Otherwise, you subtract 10 and update the display of the board. If the value of the space was 10, and ends up being zero, you recursively sweep the spaces around that space — repeating every time get a space with 10, and stopping when you hit a space with a number 11–18.
Checking for a win is actually pretty easy. All the player needs to do is sweep every space that does not contain a bomb. So you can check if only 10 spaces are left with a value greater than 9, which would only be true if every space was swept except the spaces with mines, and end the game and declare the player won.
That’s pretty much it! Again, very simple logic that can be implemented in about 100 lines of code in any language. (I won’t get into the logic for flagging spaces, but you can read my web implementation to see it for yourself — it’s also quite simple.)
If you are looking for a quick programming challenge, I would recommend trying your hand at a Minesweeper port. It won’t take long!
Closing Thoughts
I hope this dive into the enduring qualities and simple mechanics of Minesweeper was a fun read. Thanks for reading!