As Stack Snippets are live on Code Review now, I wanted to do something quick in it as part of rolfl's challenge on meta. And when you make things quick, they probably get dirty. And when things get dirty, you refactor. And when you don't know how to refactor, you post it up for review.
So, as many of my previous questions has been about Minesweeper probabilities, what better thing to make than a Minesweeper game?
This minesweeper game does not have any probability-calculations or other cool stuff though, that will have to wait until version 2.0 :) It's not the multiplayer variant Minesweeper Flags either. Just plain old Minesweeper. I decided to go with the 'Intermediate' setting, i.e. 16 x 16 with 40 mines.
It has been a while since I did any real JS coding, but I don't consider myself a beginner in it.
By the way, don't be afraid if it says 'Kaboom' on your first click. It's a bug feature, not a feature bug.
Stack-Snippet with JS + HTML: (a slightly modified version can be found on github)
var elements = [];
var fields = [];
var allFields = [];
function showField(thisButton) {
var thisX = Number(thisButton.attr('data-x'));
var thisY = Number(thisButton.attr('data-y'));
var button = fields[thisY][thisX];
var number = Number(button.attr('data-value'));
thisButton.attr('data-visible', true);
if (button.attr('data-mine') === 'true') {
button.text('X');
alert('KABOOM!');
allFields.forEach(function(entry) {
entry.attr('disabled', true);
});
}
else if (number === 0) {
button.text(number);
for (var xx = thisX - 1; xx <= thisX + 1; xx++) {
for (var yy = thisY - 1; yy <= thisY + 1; yy++) {
if (fields[yy] !== undefined && fields[yy][xx] !== undefined) {
var innerButton = fields[yy][xx];
if (innerButton.attr('data-visible') === 'false') {
showField(innerButton);
}
}
}
}
}
else {
button.text(number);
}
}
var table = $('#board').find('tbody');
for (var y = 0; y < 16; y++) {
var tr = $('<tr>');
var row = [];
for (var x = 0; x < 16; x++) {
var td = $('<td>');
var button = $('<button>').text('_').attr('data-value', 0)
.attr('data-x', x).attr('data-y', y).attr('data-visible', false)
.attr('data-mine', false)
.on('click', function() {
showField($(this));
});
td.append(button);
tr.append(td);
row.push(button);
elements.push(button);
allFields.push(button);
}
fields.push(row);
table.append(tr);
}
// Generate mines
for (var mines = 0; mines < 40; mines++) {
var random = Math.floor(Math.random() * elements.length);
var field = elements[random];
var thisX = Number(field.attr('data-x'));
var thisY = Number(field.attr('data-y'));
field.attr('data-mine', true);
for (var xx = thisX - 1; xx <= thisX + 1; xx++) {
for (var yy = thisY - 1; yy <= thisY + 1; yy++) {
if (fields[yy] !== undefined && fields[yy][xx] !== undefined) {
var innerButton = fields[yy][xx];
var previous = Number(innerButton.attr('data-value'));
innerButton.attr('data-value', previous + 1);
}
}
}
elements.splice(random, 1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="board"><tbody></tbody></table>
Primary concerns:
- Is it a good idea to use
data-*
attributes to store the data? It kinda makes it quite easy to cheat... - Am I using the features of JQuery in a good way?
- Any other comments welcome! Don't be afraid to hurt my feelings, I'm more of a Java guy anyway...