AngularJS Game Programming: Making Minesweeper (Part VI)

angularjs-game-programming-making-minesweeper-blog-part-vi

Last time on “AngularJS Game Programming”: We added numbers to our minefield! Now a player can figure out where the mines are. In this post were going to keep track whether the player has won and notify them.

Win or Lose

We now have a complete minesweeper minefield. But it’s not a game until you can win or lose. Let’s add the code that checks for that. But first, let’s clearly define what it means to win.

A player wins when they uncover all the safe spots. Said another way, a player wins when the only uncovered spots left on the minefield all contain mines. If an uncovered spot contains anything other than a mine they haven’t won yet.

function hasWon(minefield) {
    for(var y = 0; y < 9; y++) {
        for(var x = 0; x < 9; x++) {
            var spot = getSpot(minefield, y, x);
            if(spot.isCovered && spot.content != "mine") {
                return false;
            }
        }
    }
    
    return true;
}

We need to check whether the player has won each time they uncover a block. To do that let’s change the ngClick we have on the td to call a function instead of what it is now spot.isCovered = false. That way we can easily add this additional logic.

Create a function called uncoverSpot() and move the current ngClick code there. Unlike our other functions this function has to be in the scope so that it can be called from the view.

So replace the code in the ngClick with ng-click="uncoverSpot(spot)", it should look like this:

<td ng-repeat="spot in row.spots" ng-click="uncoverSpot(spot)">

Update the controller to add this:

$scope.uncoverSpot = function(spot) {
    spot.isCovered = false;
};

Add the check to see if they won after the setting isCovered. If they win track it in a variable so that we can display a message to the user. Like this:

if(hasWon($scope.minefield)) {
    $scope.isWinMessageVisible = true;
}

Add the message to the HTML:

<h3 ng-if="isWinMessageVisible">You won!</h3>

Play with it at: http://jsfiddle.net/luisperezphd/UWSWy/

Next Time

In the next post we’re going to add the ability to add “lose” detection.

Part 7: Lose Detection

Comments

  1. Troy says

    A big part of playing minesweeper effectively is the use of flags. In the desktop version of minesweeper, you right click to place (and remove) a flag.

    Flags let you distinguish where you know a mine is, so you don’t click it. They also let you automatically reveal non-mine squares by right + left clicking on adjacent number squares that are satisfied.
    For example if you have a number square 1, and you know a mine is next to it and flag it, you know you can safely reveal all adjacent squares. This functionality lets you do this.

    How do you plan to implement this functionality without being able to right click?

    Also, another slightly annoying this about this web version is the clicking mechanism. Clicking on normal buttons lets you drag the mouse within that square, and still have the click register. You can even move the mouse out of the button and bring it back in, and have the click register.
    Because you’re using images, you don’t get that functionality. You also get the slightly annoying behaviour that if you move the mouse slightly too much, your click doesn’t register.
    Could you convert your game to use this?

    If you do decide to use native browser buttons, you get the benefit of having things like click states managed for you. You’d just have to define the various images for each state of the button.

    • Luis Perez says

      Hey Troy. All great points. They are a little past the scope of this series though. This series is intended to get people started and thinking about how to use angular to create a game. It should serve as a basis and framework. They can then take what they learn here and adapted, for example in the ways that you mentioned.

Leave a Reply

Your email address will not be published. Required fields are marked *