I have created a javascript version of minesweeper for a project, but I am trying to introduce an additional piece of functionality to better mimic the desktop version I remember playing.
My full code can be found at: jsfiddle
The particular function I am having difficulty with is the "clickTile()" function. The base requirement is to add the class 'selected' as well as the number of adjacent mines to the html for the clicked tile. The additional requirement I am trying to resolve is recursive autoclicking of tiles that do not have adjacent mines.
The function as it stands is:
function clickTile($tile) {
if ($tile.hasClass('mine')) {
alert('game over');
$('.mine').css("background", "red");
} else if (!$tile.hasClass("selected")){
mines = getNumberOfAdjacentMines($tile);
$tile.addClass("selected");
$tile.html(mines);
//recursively call clickTile function as long as there are no adjacent mines
if (mines <= 0) {
height = $('#field .row').length;
width = $('#field .row .tile').length / height;
rowNum = $tile.parent().prevAll('div').length
colNum = $tile.prevAll('div').length
$above = $tile // td
.parent() // tr
.parent() // table or tbody
.children('.row')
.eq(rowNum - 1) // the row above this one
.children('.tile')
.eq(colNum) // in the same column as this
;
$below = $tile // td
.parent() // tr
.parent() // table or tbody
.children('.row')
.eq(rowNum + 1) // the row below this one
.children('.tile')
.eq(colNum) // in the same column as this
;
if (rowNum > 0) {
if (!$above.hasClass('mine') && !$above.hasClass('selected')){
clickTile($above);
}
}
if (colNum < (width-1)){
if(!$tile.next().hasClass('selected')) {
clickTile($tile.next());
}
}
if (rowNum < (height-1)){
if(!$below.hasClass('mine') && !$below.hasClass('selected')) {
clickTile($below);
}
}
if (colNum > 0){
if (!$tile.prev().hasClass('selected')) {
clickTile($tile.prev());
}
}
}
}
}
To me, this SHOULD work to recursively click all tiles with 0 adjacent mines, but it does not. Can anyone help me understand where I may be going wrong with this? The behavior is very finicky.
The problem with your code is that the variables are defined without the var
keyword, so they are defined in the global scope.
In the clickTile function, you should replace
// rowNum is defined in the global scope,
// Its value is overwritten with each recursive call
rowNum = $tile.parent().prevAll('div').length
with
// rowNum has the function as a scope,
// its keeps different rowNum values for each recursive function call
var rowNum = $tile.parent().prevAll('div').length
The rowNum
(and other variables) values are overwritten by recursive calls, so further conditions will behave incorrectly
if (rowNum > 0) { // rowNum can be anything at this point
// The condition is randomly met
}
Add the var
keyword to your variables, and your code should work as expected.
More about javascript scopes here.