My rewrite of the original Minesweeper, for the web

To-do list, tic-tac-toe, snake – all great baby’s first program choices for sure. I, however, was sort of frustrated with the selection of Minesweeper implementations online, so here we are.

Check out my version at the memorable vanity domain https://minesweepe.rs. It's a static site with no ads or tracking. If you are interested in taking a peek at the code, it is available here. Scala 3 and AGPLv3.

At some point in the past, this blog post used to include more detailed descriptions of the improvements I had added to the status quo. Instead, here's a succinct list of some of them:

Responsivity means that you are greeted with the screen full to the brim of that which you came for:

A demonstration of the game filling a device's screen.

This feature combines well with touch optimisation. You can get very good times on a tablet, as proven by the screenshot below, shared by Llama who is the developer of the arguably superior Minesweeper site https://llamasweeper.com. In my defense, I started developing mine before they had published theirs :-)

A time of 10.585 seconds on intermediate level.

The above image was edited by me to include the precise stats from another screenshot. Llama had this to comment: “This is niche, but the touch performance is SO GOOD on mobile. I got a 10s game on int just now (will send screenshot later). I’m one of a few people that can play using both hands at once, so the multitouch feature is excellent for that, and makes it better even than lots of native apps.” Very kind words!

As for the new-ish algorithm, there's a need for some background information first: There is this thing called ZiNi which aims to calculate the lowest number of clicks required for a board to be solved. Its variant, Human Zini (HZiNi), is claimed to be more humanlike and comparable to an actual solve.

The thing is, every ZiNi method starts with an advantage over all fleshly beings, that advantage being Unfair Prior Knowledge (UPK). What this means is that the solvers see the full board from the start. In the case of HZiNi, the algorithm starts by opening every single zero area, which is practically impossible for a human to achieve outside of the beginner level.

Enter what I am dubbing More Human ZiNi (MH.ZiNi). It can still use UPK, but the main difference is that it starts from where the player themself started and goes on from there in a similar manner to HZiNi:

  1. Calculate the premium for each open cell.
  2. Find the cell with the highest premium.
  3. Go back to 1 if closed cells remain.
Robot illustration
It wants to be human © Hand-Drawn Goods.

I am still contemplating whether I should add a step there – after the first “else” – to instead do the more human thing of chording a cell if the number of opened cells does not cost any clicks. That sometimes even leads to more optimal solves, as the current way can be shortsighted (on purpose).

MH.ZiNi adds a more realistic efficiency goal for the player without me having to implement a proper solver. It can be beaten and it can even lose against 3BV (at least on beginner level).

Final note: An LLM was used to ask about CSS and to implement the recursive drift-free timer. There are some missing features and aspects I find lacking, but overall I'm proud of the result. Might do a V2 at some point.

Thanks for reading!