/ Games

MineSweeper implemented in CSS + HTML using the Space Toggle trick

MineSweeper implemented in CSS + HTML using the Space Toggle trick

css-sweeper from PropJockey

MineSweeper implemented in CSS + HTML using the Space Toggle trick (no JavaScript!)

css-sweeper-from-PropJockey

Win Condition

Since it's not practical to clear all the spaces when you expose an empty area (without loops or causing cyclic references), the win condition has been reduced to:

  1. Flag all the bombs
  2. Do not flag non-bombs
  3. Clear all non-bomb spaces

This also allows you to win when it comes down to a forced-guess since you can flag without consequence. If you pick right and haven't flagged any non-bombs, you win.

Mine Field Generation

The fields are only defined by where the bombs are (and that those spaces are not not-bombs).

The rest of the game, counter, numbers, etc flow from there, so the bombs can be placed anywhere, and in any number.

This is the (lazy/inefficient) script I ran before hand to generate the 16 included Fields:

var levels = [{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}]
var genlvl = (lvl) => {
  var y = ~~(Math.random() * 16)
  var x = ~~(Math.random() * 30)
  var key = `bomb-${y}-${x}`
  lvl[key] = `--${key}: ; --not-${key}: initial;`
}
levels.forEach(lvl => {
  while (Object.keys(lvl).length < 99) { genlvl(lvl) }
})
var cssoutput = ""
levels.forEach((lvl, i) => {
  var out = `    #level-${ i.toString(10).padStart(2, "0") }:checked ~ #ram {
      --level: "${ (i + 1).toString(10).padStart(2, "0") }";
      ${Object.values(lvl).join("\n      ")}
    }
`
  cssoutput += out
})
// cssoutput is the only css necessary to create new fields

CSS is a programming language thanks to the Space Toggle trick

Basics of Space Toggle:

  • if your --css-var holds a space --toggler: ;, then it can be added to anything (any number of times) without changing the value
      --toggler: ;
      --red-if-toggler: var(--toggler) red;
      background: var(--red-if-toggler, green); /* will be red! */
    
  • if your --css-var holds initial --toggler: initial; (or was never defined), then it can be added to anything to force-fallback when referenced
      --toggler: initial;
      --red-if-toggler: var(--toggler) red;
      background: var(--red-if-toggler, green); /* will be green! */
    
  • Space Toggles can be combined for AND logic: --red-if-togglersalltrue: var(--tog1) var(--tog2) var(--tog3) red;
  • Space Toggles can be combined for OR logic: --red-if-anytogglertrue: var(--tog1, var(--tog2, var(--tog3))) red;
  • Checkboxes (and radio buttons) make a great source for space toggles (shout out to @RockStarwind for that idea)
      #common-css-var-area { /* default any "not" values to truthy */ --not-flagged: ; }
      #mycheckbox:checked ~ #common-css-var-area { --flagged: ; --not-flagged: initial; }
      #anotherbox:checked ~ #common-css-var-area { --open: ; }
      #common-css-var-area {
        --yellow-if-flagged-and-open: var(--open) var(--flagged) yellow;
        --white-if-not-flagged-and-open: var(--open) var(--not-flagged) white;
        --red-if-flagged: var(--flagged) red;
        color: var(--yellow-if-flagged-and-open, var(--white-if-not-flagged-and-open, var(--red-if-flagged, black)))
      }
      /* color will be black if not flagged and not open */
    

GitHub

CodeTea

CodeTea

A Nice collection of often useful examples done in HTML JavaScript CSS.

Read More