256-byte Minesweeper
====================

This is my take on the 256 Minesweeper game.
Released at Lovebyte 2025, category Wild Showcase (high-end nanogame)

Inspired by Chris Mumma's 2011 version, itself inspired by James David
Chapman.


Requirements:
-------------
VGA for mode 13h
286+ CPU for 'popa', 'pusha', 'imul d,s,i' instructions.
DOS Mouse driver. The presence of the driver is NOT checked!

The program has been tested under DOSBox, DOSBox-X, MS-DOS 6.22,
FreeDOS 1.3 and Win98.

Note that as of now, Dosbox seems to have a bug where INT 33h
function AX=00h does not reset the mouse button press counters.
That means if you have clicked on the screen before starting the game, the
last of these clicks will be accounted for when the game starts.


Build:
------
Build with nasm.

  nasm -f bin -o msweep.com msweep.asm

A Makefile is provided, but the development was done under Linux, it may
need to be adapted for a different environment.


Non-negociable features:
------------------------
Some features I thought were the absolute minimum for the release:
- Graphics mode:
  I want the mouse pointer to be an arrow, not a block ;-)
- Flag a cell:
  Player must be able to right-click a cell to mark it flagged
- Colors:
  Visual contrast for flagged cells is important
- Full 8-way auto-reveal
  Revealing a cell with no neighbour mines must automatically expand the
  area that is uncovered, stopping at flagged cells and cells having mines
  as neighbours ("flood-reveal").


Left out features:
------------------
- Abort the game by pressing the Escape key
- Restore video mode on exit
  On the other hand, this allows to see if the player has won or lost, so
  this would need a wait for keypress.
- Tri-state flagging, cycling between unflagged, flagged, question mark.
- Middle-click on a cell that has all is neighbours mines already flagged
  to reveal all other neighbours
- Test for the availability of the mouse driver
- Visual clue of wrongly placed flags and unflagged mines when game is lost
- Map generation *after* the first click to make sure the first cell clicked
  has no neighbour mines, or at least is not a mine
- Display the number of unflagged mines left
- Timer



Building the map
----------------
The map is 19 cells wide (plus one for the right border) and 12 cell high,
which is 240 positions, a value that conveniently fits into a byte.

The main idea is taken from Chris' code: first fill too much memory with a
byte value that represents the border of the map. In a second pass, clear
some lines to make the cells where the game takes place. Finally, a third
pass is made to place the mines in the map.



Colors
------
I first wanted to use red for the bombs and flags, and colors from 8 to 15
for values 1 to 8 (black for 0, so it doesn't show). But I couldn't get it
to fit, so the color is instead the ASCII value of the character minus 8.
This leads to a nice gradient for numbers and makes the star and flag
characters purple.




Applying a function to the neighbours of a cell
-----------------------------------------------
The code snippet at the very end of the program, labeled NeighApply, is called
to apply a function to all eight neighbours of the cell pointed by [DI+BX]. It
is first used to increase the value of the cells surrounding a mine when the
map is created. Later on, the same section of code is used as the recursing
part of the FloodReveal function.



