How to Code and Solve Minesweeper in Python

Level: Beginner

Problem Statement

Minesweeper is a game with a square grid. There are numbered squares and bomb squares. A numbered square represents how many bombs that are neighbors to that square. The user will use these numbers to predict and avoid bombs. The user wins by identifying and selecting all numbered squares.

Setting up the board and Dropping Bombs

We first need to set up the board by creating data structures and selecting positions for the bomb. I thought of this as "bomb dropping," meaning, randomly selecting spaces and dropping bombs if it is empty. If there is already a bomb, iterate in the loop again.

First, let's create some basic data structures:

Missing image :(

"Size" is the length of the board. I'm using single dimensional arrays to represent Minesweeper. The arrays are of length Size * Size , because it is a square board.

They are initially all zeroes. BombMap represents 1 if the square is a bomb and 0 otherwise. We will "Drop Bombs" in a moment, to initialize the board. WasDiscovered represents 1 if the square is revealed and 0 otherwise.

We will now drop bombs to create BombMap. A loop runs until a condition is met. In this case, we are iterating until we have "Dropped" 10 bombs.

Missing image :(

The following is what I see when running python minesweeper.py with appropriate debug logs, which tell me the solution board.

Missing image :(

Providing input options

There are two modes -- RNG and Guess mode. To play yourself, use guess mode. Missing image :(

Neighbors

Let's quickly assert what a neighbor is in Minesweeper. A neighbor includes Left, Right, Up, Down, and all diagonals. There are clean ways to do this, but we will do a very messy way.

A few rules about neighbors: Neighbors cannot be off of the board. Neighbors cannot be "between the mod" as shown below.

Game Loop

We use another loop to play the game. We will loop until all numbered squares are discovered (undiscovered = 0). Every time we discover a square, we decrement undiscovered. DiscoveredBombLocations will be used for a future feature-- a solver for Minesweeper, which accounts for numbered squares.

Missing image :(

Consider what happens in one round of the game. There are 3 options -- You are touching a) an untouched bomb square, b) an untouched numbered square, or c) an touched numbered square. In a), we give an error message and quit(), as the player has lost. In b), we update our variables -- we decrement undiscovered by 1, and store the data in other structures. In c), we give an "invalid input" message.

If the user gets past the loop, that means they've discovered all of the numbered squares, so we can give them a success message and end the game.

Missing image :(

Future improvements

- Create solver for Minesweeper