# 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. ```bash 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: ```bash 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: ```bash 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 ```bash 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//`. Nothing has to be installed on the machine that runs them. ```bash ./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_COLOR` is set; `--ascii` swaps 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.