Java Reference
In-Depth Information
Listing 7-17. The MineField cascade method
private gameState cascade(int x, int y) {
if (x < 0 || y < 0 || x >= rows || y >= columns) {
return gameState.CONTINUE;
}
Mine thisMine = mineField[x][y];
if (thisMine.hasMine()) {
return gameState.CONTINUE;
}
if (!thisMine.isCleared()) {
thisMine.clear();
emptiesRemaining--;
if (emptiesRemaining == 0) {
return gameState.WIN;
}
}
if (countAdjacentMines(x, y) > 0) {
return gameState.CONTINUE;
} else{
for (int i = x - 1; i <= x + 1; i++) {
for (int j = y - 1; j <= y + 1; j++) {
if (i < 0 || j < 0 || i >= rows || j >= columns) {
continue;
} else if (!mineField[i][j].isCleared()) {
cascade(i, j);
}
}
}
}
return gameState.CONTINUE;
}
The cascade method handles the hardest task, which is figuring out whether multiple locations
should be cleared when one location is cleared. It uses a simple version of the well-known flood fill
algorithm, checking for adjacent clear locations rather than pixels of the same color (as you would
expect from a flood fill in a paint program). It works by checking the location the player clicked (not
right-clicked), checking every location next to (including diagonally) that location, checking all the
locations next to those locations, and so on, until we finally run out of locations to check. To make that
algorithm work requires recursion again. As you can see near the bottom of the method, the cascade
method calls itself.
Given that a large area without mines can result in a single click clearing a lot of locations, the
cascade method might end up calling itself quite a number of times. I haven't tested the method for the
purpose of seeing how often it is called, but we would not be surprised to see 100 calls in a worst-case
scenario. If you are interested in knowing that, add a counter variable (it has to be an argument to the
method), increment it each time you enter the method, and print that value to the console. Then, when
you play a game, you see how many calls to the cascade method happen.
Another bit of complexity that crops up in the cascade method is the need to check for boundaries.
If the current location is at the edge of the game area, checking an adjacent location can result in an
ArrayOutOfBounds exception, which wouldn't be much fun. So we have an if statement check all four
boundaries and not call the cascade method again if doing so would result in an impossible location.
Search WWH ::




Custom Search