I am building a Minesweeper game with vanilla JavaScript. I have a Grid class that handles logic on the grid, a Space class that acts basically as a container for space properties, and a Game class that handles game logic.
In the Grid class, I have a method called openAdjoiningSpaces
. The intended behaviour of this method is to open all connected spaces on the board in each direction starting with the clicked empty space, and terminating when the next space borders a mine. If you aren't familiar with Minesweeper you can see this behaviour at http://minesweeperonline.com/.
The openAdjoiningSpaces
method calls another method, getBorderingSpaces
. This method accepts the clicked space as an argument and returns an array that contains each bordering space, including spaces that touch at the corners.
When openAdjoiningSpaces
is called, it first gets the bordering spaces that don't contain a mine and puts them in an array called toOpen
. The method then uses a while loop. In the while loop, each space in toOpen
is opened, and then for each space that is opened, its bordering spaces are obtained and if they are empty, they are added to an array called next
. At the end of the loop, if the next
array has a length greater than 0, the toOpen
variable is reassigned to next
, otherwise the loop terminates.
This should cause the desired behaviour, but it isn't. Each time I rewrite it in another way, it either crashes the browser (even though it is not an infinite loop), or it only opens up the surrounding spaces of the clicked space and then terminates. Here is the method itself:
openAdjoiningSpaces(space)
{
if (space.isEmpty) {
let loop = true;
var toOpen = [ ...this.getBorderingSpaces(space).filter(space => !space.hasMine)];
while (loop) {
const next = [];
toOpen.forEach(space => {
this.openSpace(space.id);
const neighbouring = this.getBorderingSpaces(space);
neighbouring.forEach(space => {
if (!space.hasMine && space.isEmpty) {
next.push(space);
}
});
});
if (next.length > 0) {
toOpen = next;
break;
} else {
loop = false;
}
}
}
}
I have been trying to create this space opening behavior for two days now. Each time I get close to succeeding, the grid still displays some kind of buggy behavior. All this afternoon I have continually tried to rewrite this method in different ways, to no avail. I'm at my wits end and really need some outside input. Please don't hesitate to ask me to clarify anything about the code. One thing I should clarify is that Space objects have two separate properties hasMine
and isEmpty
. The first just refers to whether the space has a mine or not. The second refers to whether it contains a number. Maybe a design flaw, I don't know but I thought I should mention that.