How to Make a Minesweeper Game in Python Easily

Play and code your own Minesweeper game. Follow this beginner-friendly Python guide with step-by-step explanations and full source code.

Minesweeper isn’t just a classic puzzle — it’s also a perfect coding project for beginners. In this guide, we’ll build Minesweeper in Python step by step, explaining every line in plain English. You’ll learn how to create the grid, plant bombs, calculate hints, and handle user moves. By the end, you’ll not only have a working game but also a deeper understanding of Python programming.


What you’ll learn

You’ll read a compact Minesweeper game in Python.
We’ll break the script into small parts.
Each line gets a clear, plain-English note.
By the end, you can run it, tweak it, and make it your own.

Tip: if you like AI coding helpers, you may also enjoy our guides on Claude Code, Qwen 3 Coder, and AgentMode in Lovable.


Quick overview of the script

The game:

  • Creates a square grid.
  • Plants bombs at random spots.
  • Fills other cells with numbers 0–8.
  • Lets you dig until you win or hit a bomb.
  • Prints a clean board after every move.

File header and imports

import random
Use Python’s random number generator to place bombs.

import re
Splits user input like “row,col”. The re module makes this easy.

Why both?
Random handles the game’s uncertainty.
Regex keeps inputs flexible and forgiving.


The Board class — your game’s brain

Class purpose

Encapsulates all board data and behavior.
Track dimension, bombs, revealed cells, and printing.

__init__(self, dim_size, num_bombs)

  • Saves the grid size and number of bombs.
  • Calls make_new_board() to create cells and plant bombs.
  • Calls assign_values_to_board() to compute neighbor counts.
  • Creates self.dug = set() to remember revealed coordinates.

Key idea:
A set makes “already dug?” checks fast.


Making the empty grid and planting bombs

make_new_board(self)

  1. Create the 2D listboard = [[None for _ in range(self.dim_size)] for _ in range(self.dim_size)]
    • Builds a square grid filled with None.
    • Each inner list is a row.
  2. Plant bombs
    • Tracks bombs_planted = 0.
    • While bombs remain:
      • Picks a random location from 0 to dim_size**2 - 1.
      • Converts that flat index to (row, col) with:
        • row = loc // dim_size
        • col = loc % dim_size
      • Skips if a bomb is already there ("*").
      • Otherwise sets board[row][col] = "*" and increments the count.
  3. Return the board
    Now you have bombs in random cells.
    Others are still None.

Why flat index math?
It avoids double loops.
You map one number to a row and column cleanly.


Counting bombs around each cell

assign_values_to_board(self)

  • Loops through every (r, c).
  • Skips bombs.
  • Replaces None with the count from get_num_neighboring_bombs(r, c).

get_num_neighboring_bombs(self, row, col)

  • Looks at up to 8 neighbors:
    • Top, bottom, left, right, and diagonals.
  • Uses max() and min() to stay inside the grid: for r in range(max(0, row-1), min(self.dim_size - 1, row + 1) + 1): for c in range(max(0, col-1), min(self.dim_size - 1, col + 1) + 1):
  • Skips the center cell itself.
  • Counts neighbors where self.board[r][c] == "*".
  • Returns the total.

Result:
Every safe cell shows how many bombs touch it.
Zero means a clear patch.


Digging logic (the core gameplay)

dig(self, row, col)

  • Adds (row, col) to self.dug.
  • If it’s a bomb ("*"), returns False → game over.
  • If it’s > 0, returns True → shows that number and stops.
  • If it’s 0, it reveals neighbors too:
    • Loops through adjacent cells.
    • Skips cells already dug.
    • Calls self.dig(r, c) recursively.

Why recursion?
Zero means “no bombs nearby”.
So you reveal its neighbors automatically, like real Minesweeper.


Pretty-printing the board in the console

__str__(self)

  • Builds a visible_board first:
    • Shows numbers for dug cells.
    • Shows blank space for hidden cells.
  • Computes column widths so the grid aligns.
  • Prints a header row with column indices.
  • Prints each row with | separators.
  • Returns a string so print(board) looks clean.

User experience matters.
A tidy board keeps the game readable.
It feels like a real puzzle.


The play() function — the game loop

Setup

  • Creates board = Board(dim_size, num_bombs).
  • Sets safe = True.

Loop condition

  • Continues while dug cells < total safe cells.
  • Prints the board each turn.

Read input

  • Prompts: “Where would you like to dig? Input as row,col:”
  • Uses: user_input = re.split(",(\\s)*", input(...)) row, col = int(user_input[0]), int(user_input[-1])
  • Accepts “0,0” or “0, 0”.
  • Validates bounds.
  • Asks again if out of range.

Dig and check

  • Calls safe = board.dig(row, col).
  • Breaks if you hit a bomb.

Ending the game

  • If safe stays true, prints a victory message.
  • If not:
    • Prints “SORRY GAME OVER :(”.
    • Reveals the whole board by setting board.dug to include all coordinates.
    • Prints the final grid.

Run guard

if __name__ == "__main__":

  • Calls play() only when the file runs directly.
  • Keeps the module import‑friendly.
  • A small best practice with big benefits.

Function map (cheat sheet)

Function / PartWhat it doesWhy it exists
Board.__init__Sets size, bombs, board, values, dug setCentralizes setup
make_new_boardBuilds the grid, plants bombsRandom placement
assign_values_to_boardComputes numbers for safe cellsPrecomputes hints
get_num_neighboring_bombsCounts adjacent bombsEfficient lookups
digReveals cells and expands zerosCore gameplay
__str__Renders the board nicelyGood UX
playHandles input and win/loseGame loop
__main__ guardRuns game on direct execClean imports

Try it, then extend it

Add:

  • Flags: mark suspected bombs with F.
  • Input safety: handle bad input gracefully.
  • Timer or score: track speed or moves.
  • Difficulty presets: easy, medium, hard.
  • Colors: ANSI colors for numbers and bombs.

Want to go further with automation and AI tools around coding? Read our guides on RunAgents and AWS AgentCore.


Conclusion

Now you understand a Python Minesweeper tutorial end to end.
The Minesweeper game code is small, yet complete.
Tweak it. Add flags. Improve the UI.
Then ship your version and have fun.

If you’d like help turning ideas into polished tools, we’re here. Explore our services at Ossels AI and keep building smarter.

Next reads:

Posted by Ananya Rajeev

Ananya Rajeev is a Kerala-born data scientist and AI enthusiast who simplifies generative and agentic AI for curious minds. B.Tech grad, code lover, and storyteller at heart.