JSFiddle - React, Tailwind, and code Playground
by cmacrander
HTML
<!DOCTYPE html>
<html>
<head>
<title>Minefield</title>
</head>
<body>
<table id="minefield">
<tr>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
</tr>
<tr>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td class="hidden"></td>
<td...
CSS
#minefield {
border-collapse: collapse;
font-size: 1.0em;
font-family: Verdana, sans-serif;
}
#minefield td {
width: 19px;
height: 20px;
border: 1px solid black;
text-align: center;
}
#minefield td.hidden {
background-color: grey;
}
#minefield td.revealed {
background-color: white;
}
JavaScript
// ** GLOBALS ** //
var fieldWidth = 30;
var fieldHeight = 16;
var totalSquares = fieldHeight * fieldWidth;
var totalMines = 99;
var minefield;
// ** MAIN ** //
dojo.addOnLoad(function() {
minefield = generateMinefield();
// create all the square widgets
var index = 0;
dojo.query("td", "minefield").forEach(function(node) {
Square.list.push(new Square(node, index));
index++;
});
// allow them to look at their surroundings
Square.list.forEach(function(square) {
square.init();
});
// find a place to start sweeping.
var started = false;
while(!started) {
var s = Square.list[randomIndex()];
if(s.d === 0 && !s.isMine()) {
s.reveal();
started = true;
}
}
while(sweep());
});
// ** CLASS MapSet ** //
// Purpose: to hold and analyze information about possible
// arrangements of mines around a square. Can combine with
// other map sets to determine if any certainties can be
// established about where mines must be or must not be.
function MapSet(square) {
if(!(square instanceof Square)) console.error("Bad input for MapSet", square);
var indices = []; // list of indices of hidden unmarked neighbors
this.maps = []; // will contain all maps
// get indices of hidden neighbors
square.neighbors.forEach(function(n) {
if(n.isHidden && !n.isMarked) indices.push(n.index);
});
// generate possible arrangements of mines (simple lists of 0s and 1s)
var samples = Util.createBinomialSamples(square.hu, square.r);
// match up the arrangements with the indices and store them as maps
samples.forEach(function(sample) {
var map = [];
for(var x = 0; x < indices.length; x++) {
map[indices[x]] = sample[x];
}
this.maps.push(map);
}, this);
}
// combines mapSets, testing all combinations and keeping
// only those that completely agree,...