🌊 Section 6: Reveal + Zero Flood
📝 Summary
In this section, you will add the reveal() method inside the Board class. This method reveals cells, performs a “zero flood” (so empty areas open up automatically), checks for win/loss, and returns a list of changed cells so the Tkinter UI can repaint only what needs updating.
✅ Checklist
- Add a
reveal(self, r, c)method insideclass Board(aftertoggle_flag). - If the game is over, ignore reveal attempts.
- If mines are not placed yet, place them on the first click (safe first click).
- Ignore reveals on flagged or already-revealed cells.
- If the player reveals a mine, set game over and return the changed cell.
- Use a queue (
deque) to flood-reveal connected zero-adjacent cells. - After revealing, check the win condition and update
_game_over/_win. - Return a list of changed coordinates for the UI.
🎓 Core Concepts
First-click safety: In Minesweeper, the first click should never lose. That’s why we delay mine placement until the first reveal. When reveal() runs for the first time, it calls _place_mines(r, c) so the clicked cell (and its neighbors) stay safe.
Zero flood: When a cell has adjacent == 0, it means there are no mines around it. Minesweeper reveals a whole region of connected zeros automatically, plus the numbered “border” cells around them. We implement that flood using a queue.
Breadth-first search (BFS) with deque: BFS is a pattern for exploring “neighbors” in layers. A deque lets us efficiently pop from the front (popleft()) as we work through cells to reveal. This is a good match for flood fill because it stays responsive and gives us a clean list of changes to send to the UI.
Changed-cells list: Instead of redrawing everything, the model returns [(r, c), ...] so Tkinter can update only the buttons that changed. This keeps the UI fast.
💻 Code to Write (inside class Board in model.py)
Type this by hand so you understand each piece. (You already imported deque at the top of model.py in an earlier section.)
🧠 Code Review & Key Concepts
if not self._mines_placed: self._place_mines(r, c) guarantees mines exist after the first click and keeps the first click fair.
if start.is_flagged or start.is_revealed: return [] prevents accidental reveals on flagged cells and avoids double-counting revealed cells.
The “mine path” reveals exactly one cell, sets _game_over, and returns immediately. This gives the UI a clean signal to stop normal play.
The BFS loop uses deque:
- q = deque([(r, c)]) starts the flood from the clicked cell.
- popleft() processes the next cell to reveal.
- Zero cells enqueue neighbors so the empty region expands outward.
The win check compares _revealed_count to the total number of safe cells. When they match, the player has revealed everything that is not a mine.
🧪 Test File (create s6_test.py)
This test checks three key behaviors: - A flagged cell cannot be revealed (so the UI doesn’t accidentally open a flagged square). - Revealing a zero cell causes a flood reveal and can trigger a win when all safe cells are revealed. - After mines are placed, revealing a mine ends the game and returns a change list containing the mine cell.

