Creating a Game Like Minesweeper in Flutter

Explore Flutter’s capability to create game UI and logic by learning to create a game like classic Minesweeper. By Samarth Agarwal.

4.1 (8) · 1 Review

Download materials
Save for later

Developing games with Flutter isn’t explored very much. In this tutorial, you’ll build a game like the classic Minesweeper in Flutter. You’ll learn to create the game’s UI and write clean, modular code to implement algorithms that bring the game logic to life.

Here’s a preview of the app you’ll build:

Minesweeper Flutter final project preview

To build this game, you’ll use several Flutter widgets to create the UI and write algorithms to implement the game logic.

While building this app, you’ll learn about:

  • Minesweeper’s logic and game theory.
  • Implementing the game user interface using Flutter widgets.
  • Building a dynamic and random game with a specific difficulty every time.
  • Using the GestureDetector widget to detect taps and long-presses.
  • Optimizing the game to avoid edge cases.
Note: This article assumes you know the basics of the Flutter framework, including common widgets and their properties. To learn about Flutter from scratch, check out the Flutter Apprentice book.

Getting Started

Download the starter project by clicking Download Materials at the top or bottom of the tutorial.

Unzip the downloaded file and open it with Android Studio 4.1 or later. You can use Visual Studio Code instead, but if you do, you’ll need to tweak some instructions to follow along.

Click Open an existing Android Studio project and choose the starter folder from your unzipped download.

Run the flutter create command in the starter folder to generate the android and ios folders. Next, download your dependencies by double-clicking pubspec.yaml on the left panel and then clicking pub get at the top of your screen. To avoid problems, delete the test folder, which Flutter generated when you executed the flutter create command.

Finally, build and run to see this:

Starter project on iOS Simulator

Here are a few files you’ll see in the starter project’s lib folder:

  • main.dart is the main file that acts as the entry point for the app. It contains MyApp, which contains MaterialApp. This widget uses MyHomePage as the child. This widget contains the game’s only screen.
  • cell.dart contains the model for the cells that you’ll lay out in a grid on the screen. It contains a class called CellModel.
  • cell_widget.dart contains CellWidget, which is a visual representation of a cell on the screen.

Introducing the Minesweeper Flutter Game

Before you get into writing the code to build this Flutter game, it’s important to understand the basics of Minesweeper. It’s a logical single-player game that requires careful assessment of the cells on the board before making the next move. This continues until the player clears the board — or hits a mine. The game originates from the 1960s, and it has been written for many computing platforms in use today. It has many variations and offshoots. Simply do a quick Google search for “Minesweeper”, and you can play a web version of the game right in your browser.

For this project, you’ll need to understand Minesweeper in more detail.

Playing Minesweeper

Minesweeper is a simple — but not to be underestimated — puzzle game that consists of a rectangular board of tiles laid out on the screen. The game’s objective is to clear the board without detonating any hidden “mines”, or bombs, by using help from numbers indicating how many mines are in neighboring cells.

The player selects a cell to uncover it. If the cell has a mine, the game is over. Otherwise, the cell displays the number of mines in the cell’s Moore neighborhood. Using these numbers, the player uncovers nearby cells. This continues until either they hit a mine or uncover all the non-mine cells on the board. Therefore, understanding the numbers in the cells is crucial to completing the game.

While the game is in progress, the player can flag a cell for their reference if they suspect it to be a mine. This has no impact on the game logic but allows the player to keep track of the suspected cells. A flagged cell can be either a mine or a non-mine.

Once the player uncovers all the non-mine cells, the game is complete. In this Minesweeper Flutter version, the game restarts with increased difficulty — the size of the grid increases, and the number of mines also increases.

Understanding the Moore Neighborhood

A Moore neighborhood is a 3×3 grid of cells. It consists of one central cell and all its surrounding cells, including cells with sides adjacent to the central cell and those that touch its corners. The Moore neighborhood is named for Edward F. Moore, a computer scientist known for his work in topics including cellular automata and finite state machines. Here’s a diagram of a cell with its Moore neighborhood, with numbers indicating cell coordinates:

Starter project on iOS Simulator

In Minesweeper, when the player selects a non-mine cell, the cell reveals a number. This represents the number of mines in the surrounding eight cells, or the cell’s Moore neighborhood. Using the number, the player can make a calculated guess about the next non-mine cell on the board that they can safely uncover. Keep in mind that no mines are uncovered at any point in the game. Tapping a cell with a mine is the only way to uncover a mine, and that ends the game.

When the player taps a non-mine cell, the game also uncovers all the non-mine cells in its Moore neighborhood. As a result, the non-mine cells in overlapping Moore neighborhoods are also uncovered, and this continues until there are no more non-mine cells in the Moore neighborhood of an uncovered cell. You use recursion to implement this in the code.

In the code, you’ll write unrevealRecursively, which takes in a CellModel object and uncovers the cells in the Moore neighborhood recursively.

Understanding the CellModel Class and Properties

Inside cell.dart, you’ll find the definition of the class CellModel. This is the foundational model class you use to keep track of the cells on the board in the memory. You also use this class to represent the cell visually in combination with CellWidget.

In the game, you store all the cells in a 2D array. Since you’re using Dart, you’ll create a List to store all the cells. So, each cell will have a row number and column number. With this in mind, now look at the properties of the CellModel class:

  • x is an integer that stores the cell’s column number.
  • y is an integer that stores the cell’s row number.
  • isMine is a boolean that stores true if the cell is a mine and false if it isn’t. The default value is false.
  • isRevealed is a boolean variable that stores true if the cell has been uncovered or false if it hasn’t.
  • value is an integer variable that stores the number of mines in the Moore neighborhood of the cell. The default value is zero.
  • isFlagged is a boolean variable that stores true if the player has flagged the cell or false if not. The default value is false.