Minesweeper
Classic implementation of the minesweeper game where the goal is to reveal all the cells without hitting a mine.
Author: Dobrin David-Andrei
GitHub Project Link: https://github.com/UPB-PMRust-Students/proiect-ddavid03dda
Description
Classic implementation of the minesweeper game where the goal is to reveal all the cells without hitting a mine. Also several difficulty levels that increase the number of mines on the map. The player can see in a menu the battery status and select the difficulty before the game starts and then play until he loses or wins.
Motivation
It was a favorite game I used to play as a kid when the internet was down. I wanted to build a physical version I could keep around the house—complete with sounds and vibration—to give it a fresh, tactile feel.
Architecture
- Raspberry Pi Pico 2 W as central control unit, running the game logic in Rust.
- Vibration motor to signal when the player hits a mine (loss).
- Buzzer for sound effects—menu navigation, tile selection, win/loss alerts.
- ILI9341 LCD to display the menu, battery status, and game grid.
- Buttons for cursor movement, selection, and menu control.
Log #
Week 5 – 11 May
I have made the first steps in the project by choosing the hardware components and the software libraries that I will use. The ILI9341 LCD will be used to display the game grid and messages. I have also chosen to use a vibration motor for haptic feedback and a buzzer for audio feedback.
Week 12 – 18 May
I have soldered both Raspberry Pi Pico 2 W, the main controller, and the Raspberry Pi Pico 1 W used as the debugger. I connected the all the buttons, the lcd, the buzzer and the vibration motor to the microcontroller. I build the schematic of the project in kiCad.
Week 19 – 25 May
I have implemented the game logic in Rust, including the difficulty selection menu, grid generation, tile revealing, and win/loss conditions. I also added the buzzer and vibration motor functionality for feedback on game events. The LCD displays the game grid and messages.
Hardware
-
Raspberry Pi Pico 2 W
- Purpose: Main controller.
- Function: Runs the Minesweeper game logic in Rust, reads button inputs, and drives the display, buzzer, and vibration motor.
-
Vibration Motor
- Purpose: Haptic feedback.
- Function: Vibrates briefly when the player uncovers a mine (loss).
-
Buzzer
- Purpose: Audio feedback.
- Function: Emits tones for menu navigation, tile reveals, and win/loss alerts.
-
ILI9341 LCD
- Purpose: Visual interface.
- Function: Displays the difficulty menu, battery status, game grid, and end-game messages.
-
Push-buttons (×5)
- Purpose: User controls.
- Function: Up, Down, Left, Right for cursor movement; Select for revealing tiles and confirming menu choices.
Hardware Overview
- The Raspberry Pi Pico 2 W orchestrates all inputs and outputs, executing the Minesweeper logic.
- Push-buttons let the player navigate menus and move the cursor across the minefield.
- The ILI9341 LCD renders the game grid, menus, and battery level in real time.
- The Buzzer provides immediate audio cues for safe tile reveals, mine hits, and victories.
- The Vibration Motor delivers a tactile buzz when a mine is uncovered, reinforcing the loss event.
Hardware video that showes that everything connected workes as expected: https://imgur.com/WwEwjHi .
Schematics
Bill of Materials
Device | Usage | Price |
---|---|---|
Raspberry Pi Pico 2 W | Main microcontroller | 80 RON |
Vibration motor module | Loss feedback vibration | 15 RON |
Colored wires male–male (40 × 10 cm) | Wiring between Pico and peripherals | 5 RON |
Colored wires male–female (40 × 15 cm) | Wiring sensor/buttons | 8 RON |
Colored wires female–female (40 × 15 cm) | Breadboard‐to‐module wiring | 7 RON |
Passive buzzer (3.3 V) | Sound effects | 1 RON |
NPN Transistor 2N2222 TO-92 | Driving buzzer/vibration motor | 0.17 RON |
Breadboard HQ (400 pts) | Prototyping | 4.50 RON |
Resistor 0.25 W 2.2 kΩ | Current limiting | 0.10 RON |
Diode 1N4007 | Flyback protection | 0.50 RON |
40-pin male header, 2.54 mm (×5) | GPIO breakout | 5 RON |
ILI9341 LCD (2.4″, SD slot) | Display | 67 RON |
Push-buttons × 5 | User input | 10 RON |
Software
Library | Description | Usage |
---|---|---|
rp2040-hal | Hardware Abstraction Layer for Raspberry Pi Pico | GPIO, PWM, ADC, timers |
embedded-hal | Common traits for embedded hardware access | Digital I/O, SPI bus, delay timers |
embedded-graphics | 2D graphics library for embedded displays | Rendering grid, menus, battery indicator |
ili9341 | ILI9341 TFT display driver | SPI communication with the LCD |
panic-halt | Minimal panic handler | Halts MCU on unrecoverable errors |
nb | Non-blocking I/O traits | Debouncing buttons, reading battery level |
Software Diagram
SoftWare Design
The software is structured around the main game loop, which handles input, updates the game state, and renders the display. Key components include:
- Game State Management: Tracks the current difficulty, grid state, cursor position, and game status (ongoing, won, lost).
- Input Handling: Reads button presses to move the cursor, select tiles, and navigate menus.
- Display Rendering: Uses the
embedded-graphics
library to draw the game grid, menu options, and status messages on the ILI9341 LCD.
Software Functions
The software is organized into several key functions and modules, each responsible for a specific aspect of the game:
Display Functions
draw_title
Renders the "Minesweeper" banner at the top of the screen.
draw_menu
/ draw_menu_option
Animated difficulty selection UI.
draw_grid
Draws the minefield, cursor, numbers, and covered tiles.
draw_mine_icon
, draw_flag_icon
Vector graphics used for mines, flags, and menu art.
highlight_cell
, redraw_cell
, reveal_cell
Fine‑grained cell updates to keep frame‑rate high on the RP2040.
Game Logic Functions
has_mine
Returns true if the current cell contains a mine for the active difficulty.
count_adjacent_mines
Counts the eight neighbouring cells to compute the number overlay.
flood_fill_reveal
Recursive flood‑fill algorithm that reveals connected empty cells.
check_win_condition
Checks whether every safe cell is revealed (player victory).
reveal_all_mines
Exposes mines (or flags) when the game ends.
play_victory_melody
Plays an 8‑bit style jingle via PWM.
Feedback & Sound Functions
play_victory_melody
Plays a rising major arpeggio and sustained high C when the player wins.
Inline PWM bursts give crisp "clicks" on menu selections and tile reveals.
Photos and Videos