A playable console Minesweeper (arrow keys, chording, flags, question marks, pause, difficulty presets) plus a deduction-and-guess solver that can play the game headlessly. Game logic lives in src/Minesweeper/Game and has no console dependencies, so it is covered by 65 unit tests. Includes publishing helpers for self-contained, trimmed single-file binaries (publish.sh) and an .editorconfig that the sources conform to: UTF-8 BOM and 4-space indents for C#, 2-space indents for project files, LF endings and 2-space indents for shell scripts, System-first usings, no redundant `this.`, and s_/ _ prefixed private static and instance fields.
Minesweeper
A terminal game of Minesweeper in C# for .NET 10, plus a built-in solver so the game can be played, scripted, and tested without a keyboard.
dotnet run --project src/Minesweeper # play (Beginner)
dotnet run --project src/Minesweeper -- -d expert
dotnet run --project src/Minesweeper -- --auto # watch the solver play
Playing
| Key | Action |
|---|---|
arrow keys, Home, End |
move the selector |
space / enter |
open a square, or chord when standing on a number |
c |
chord the number under the selector |
f (or /) |
flag a suspect square |
q (or ?) |
question mark a square |
p |
pause (freezes the clock) |
n |
new game on the same board |
d, 1, 2, 3 |
next difficulty, or jump to Beginner / Intermediate / Expert |
s |
dump the board as text, then return |
h or F1 |
key list |
esc |
quit and print the final board |
Rules are the classic ones: the first click is never a mine (and by default opens an area), a number with exactly as many flags around it as it needs opens the rest, and flagged squares hold back a flood fill. Losing shows every mine and marks flags that were on safe ground.
Options
--help lists everything. Highlights:
minesweeper -d intermediate # 16x16 with 40 mines
minesweeper -s 30x20x120 # any board up to 120x60
minesweeper -s 12x8 -m 5 # size plus mine count
minesweeper --seed 42 # reproducible mines and solver guesses
minesweeper --compact --ascii # one plain ASCII character per square
minesweeper --no-color # monochrome (NO_COLOR is honoured too)
minesweeper --auto-trace --seed 7 # print every solver decision
minesweeper --list-levels # show the presets
Auto mode
--auto runs the solver in src/Minesweeper/Game/Solver.cs: it applies the two deductions
every player uses (a number touching exactly as many hidden squares as it still needs is all
mines; a satisfied number chords), then guesses the lowest risk square when logic runs out.
It prints the finished board and exits with 0 on a win, 1 on a loss, which makes it a
handy end-to-end check:
dotnet run --project src/Minesweeper -- --auto -d beginner --seed 7
Layout
| Path | What lives there |
|---|---|
src/Minesweeper/Game/Board.cs |
grid, mine placement, flood fill, chording |
src/Minesweeper/Game/MinesweeperGame.cs |
one round: safe first click, flags, win/loss |
src/Minesweeper/Game/Solver.cs |
the deduction and guessing strategy |
src/Minesweeper/Cli/ConsoleRenderer.cs |
flicker-free drawing (only changed squares are written) |
src/Minesweeper/Cli/InteractiveRunner.cs |
keyboard loop, clock, pause, difficulty switching |
src/Minesweeper/Cli/Options.cs |
command line parsing |
tests/Minesweeper.Tests |
rules, solver, difficulty and CLI tests |
The game logic has no console dependencies, so it can be unit tested or driven headlessly.
Building and testing
dotnet build # or dotnet run --project src/Minesweeper
dotnet test # 65 tests
Standalone binaries
./publish.sh produces a self-contained, trimmed, single-file binary for each runtime under
artifacts/<runtime>/. Nothing has to be installed on the machine that runs them.
./publish.sh # linux-x64 and win-x64
./publish.sh linux-arm64 # any runtime identifier
dotnet publish src/Minesweeper -c Release -r win-x64 --self-contained \
-p:PublishTrimmed=true -p:PublishSingleFile=true # the same thing by hand
| Binary | Size | Runs on |
|---|---|---|
artifacts/linux-x64/minesweeper |
14 MB | 64-bit Linux with glibc |
artifacts/win-x64/minesweeper.exe |
13 MB | 64-bit Windows 10 or newer |
Trimming keeps only the runtime the game touches, and the publish is warning free. Windows
binaries can be cross-compiled from Linux or macOS; --self-contained false gives a small
framework-dependent binary instead.
Notes
- Interactive play needs a real terminal. With output redirected the game says so and points
at
--auto. - Board squares are two characters wide so the field looks square; the game quietly drops to one character when the terminal is too narrow, and refuses boards that still cannot fit.
- Colors come off automatically when
NO_COLORis set;--asciiswaps the shaded blocks, flags and mines for#,F,*if a terminal struggles with them. - A board keeps at least one safe square: asking for more mines than fit is an error, and a board too small for the safe zone simply ends up with fewer mines.