JavaScript Minesweeper: Make Clues, Reveals, and the Win Rule Agree

Your board shows three flags and declares a win, although several safe squares are still covered. Another version reveals a blank region twice and increases progress each time.

Both games have counted actions instead of the state that defines completion.

Build JavaScript Minesweeper around one authoritative cell array. Each cell has a mine state, adjacent clue, revealed state, and flag state. A win means every safe cell is revealed; flags are player hypotheses, not proof that the board is cleared.

This original design uses a small developer fixture and a separate first-reveal-safe play mode. The local HTML/JavaScript example implements the bounded design; verify its behavior in the intended host before using it.

Minesweeper
Minesweeper
Open the full example ↗

Keep the fixture separate from play generation

The University of Pennsylvania's project description covers adjacent clues, blank-region expansion, mine loss, and an all-safe-cells win. Use those general rules without adopting its assignment dimensions, framework, or grading requirements. UPenn CIS 110: Game Project Description

The original developer fixture is a 5 × 5 board. Rows and columns are one-based; mines are at r1c5, r3c3, and r5c1. There are 25 cells, three mines, and 22 safe cells.

Use this separately labeled reviewer key:

Row c1 c2 c3 c4 c5
r1 0 0 0 1 Mine
r2 0 1 1 2 1
r3 0 1 Mine 1 0
r4 1 2 1 1 0
r5 Mine 1 0 0 0

Count the eight neighboring positions that exist inside the board; exclude the cell itself. For r2c2, only r3c3 is a neighboring mine, so the clue is one. For r4c2, r3c3 and r5c1 are neighbors, so the clue is two. r1c1 has zero.

The fixed fixture can lose on its first reveal if r1c5 is chosen. It is not the same mode as a randomly generated board that protects the first revealed cell. Label the distinction instead of moving a fixture mine and invalidating the key.

Reveal a zero region with visited state

A numbered safe cell reveals itself. A zero cell starts an expansion: reveal the zero and its safe neighbors, continue through neighboring zeros, and reveal bordering number cells. Do not expand through a numbered boundary, mine, or flagged cell.

Use a queue with visited tracking so the same zero is not processed repeatedly. Several zeros can share the same neighbor; that neighbor still becomes revealed only once. Check bounds before inspecting any neighbor.

Treat the revealed array as the source of progress. Repeating a reveal on an already revealed cell should have no effect. A wrong flag on a safe cell can block expansion until it is removed; do not silently unflag it to make the flood look successful.

The fixture's r1c1 zero expansion must not reveal r1c5, r3c3, or r5c1. Its covered boundary and any blocked safe flag are state to inspect, not an excuse to increment a counter until it reaches 22.

Make Reveal and Flag explicit modes

Provide native Reveal and Flag mode buttons, with the current mode visible in text. Grid-cell activation through keyboard or tap calls the same action function as pointer activation. Right-click flagging may be an additional convenience, but cannot be the only route to placing a flag.

In Flag mode, a covered cell toggles its flag without revealing it. Revealed cells cannot be flagged. In Reveal mode, a flagged cell remains protected from reveal; ask the player to remove the flag first. Empty, covered, flagged, and revealed states need distinguishable labels, not only different colors.

Check terminal status before either action. Revealing a mine causes loss, and later clicks cannot keep revealing safe cells, place flags, or change the result. A correct count must not continue to grow after the game has ended.

Generate the play board on the first actual reveal

In play mode, defer mine placement until a legal first Reveal action. Sample three distinct mine positions from the other 24 cells, then calculate all clues. Flag actions before that reveal are hypotheses and do not trigger generation.

Trying to reveal a flagged cell is not the first actual reveal. Remove its flag or select another legal cell first. Keep those actions separate from the step that establishes the play layout.

This protects the first revealed cell from a mine. It does not guarantee that its clue is zero, that a large region opens, or that the whole game can be solved without guessing. Subsequent reveals use the same layout rather than regenerating mines on each click.

Count completion from unique safe reveals

For this board, win requires 22 distinct safe cells revealed. Three flags alone do not win. Twenty-two click events do not win. Repeated reveals and flag toggles do not count as new safe cells.

Reset clears all revealed/flagged/result state, restores Reveal mode, invalidates queued callbacks or animation work, and starts a new game state. Play-mode mines are again deferred until its first actual reveal. Developer mode restores its documented fixed fixture. A callback from the old game must not reveal a square in the reset board.

Keep the developer key visibly separate from ordinary play materials, while recognizing that client-side code is inspectable. This separation is a usability convention, not a protected answer store.

Copy this prompt to specify the native game

Create an original self-contained HTML/CSS/JavaScript 5×5 Minesweeper file, complete source and manual test matrix. Cite general adjacency/zero/win-loss concepts at https://www.cis.upenn.edu/~cis110/18fa/hw/hw09/writeup.pdf without copying code/art, PennDraw, assignment dimensions or grading. No assets, network, uploads, tracking, storage or saved scores.

Separate labeled developer fixture and play mode. Fixture has mines r1c5/r3c3/r5c1, one-based coordinates, 22 safe cells. Reviewer clue rows: 0,0,0,1,M; 0,1,1,2,1; 0,1,M,1,0; 1,2,1,1,0; M,1,0,0,0. Fixture r1c5 reveal loses even if first action; do not claim fixture first-safe. Key is not a protected privacy boundary.

One authoritative cell array tracks mine/clue/revealed/flagged. Count in-bounds eight-neighbor mines, excluding self. Safe zero reveal uses a visited queue, expands zeros and reveals safe boundary numbers, never mines or flagged cells. Already revealed/visited cells do not increase progress; a wrong safe flag can block reveal until removed.

Native Reveal/Flag mode buttons and labeled grid buttons support keyboard/tap/pointer through the same action function. Flag toggles only covered cells, never reveals; revealed cells cannot flag. Reveal ignores flagged cells with explanation. Right-click optional, not sole flag route. Check game-over before every action; mine reveal loses and freezes play. Win only all 22 unique safe cells revealed, not 3 flags or 22 events.

Play mode defers layout until first legal actual Reveal action, excluding that cell and sampling 3 distinct mines from other 24 cells. Flagging/blocked flagged reveals do not generate layout. First reveal is safe, not guaranteed zero/no-guess; later reveals retain layout. Reset clears flags/reveals/result/mode, invalidates old callbacks, restores Reveal mode and defers play mines again; fixture Reset restores fixed key.

Tests: fixture r1c1=0/r2c2=1/r4c2=2; all clue counts; mine loss; zero expansion/boundary/visited duplicates; flagged-safe blocking/unflag; repeated reveal; 3 flags do not win; 22 unique safe reveal win; terminal guards; first-safe sampling distinct from the fixture; Reset during pending work; keyboard/tap parity. Check actual article width/360px with readable state text and no page-level overflow. Report performed tests separately from proposed tests; actual code/runtime/hosted NOS execution still require verification. Native source authoritative; no export/automatic update/saved progress claims.

Keep the fixture beside the state tests

Maintain the native source, separate developer fixture, and actual test results together. A reading companion should let someone trace a clue, a blocked safe flag, and the 22-cell completion condition without assuming each click advances progress.

NOS can save and render HTML. A prepared HTML explanation can present the original fixture and state contract beside the maintained game source. Verify actual hosted scripts and keyboard/touch behavior before describing a working product example; rendering alone does not prove those interactions.

Explore NOS with the state review. The useful game result is a win or loss that agrees with the same board the player has been inspecting.

Keep reading