Thursday, 6 November 2008

A Silverlight Minesweeper



Here's a simple Minesweeper-like game for Silverlight 2. It was mainly a programming exercise, so there aren't too many multimedia bells and whistles. Just a smooth transition when you open a square, and that's all. No sound. No explosions. No high score. No mines - just the letter 'M'. No automatic opening of tiles. Feel free to add the missing licks, if you like.
The board square is a Custom control with two states - "Opened" and "Closed", and two parts - a TextBlock that contains the number of adjacent mines or the letter 'M' if the square is a mine, and a Rectangle that initially covers the TextBlock. When you click a square, the state changes and the Rectangle's opacity goes to zero, thus showing the TextBlock underneath. Here's the relevant part of the ControlTemplate:
<vsm:VisualState x:Name="Closed"></vsm:VisualState>
<vsm:VisualState x:Name="Opened">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3" From="1" To="0"
Storyboard.TargetName="ClosingRectangle"
Storyboard.TargetProperty="Opacity">
</DoubleAnimation>
</Storyboard>
</vsm:VisualState>
The board is a User control that uses the square's SquareClicked event to check for won/lost conditions. You win if you open all the squares that don't contain mines. If you open a mine, you lose miserably. Here's the logic:
private void Square_SquareClicked(object sender, EventArgs e)
{
if (isPlaying)
{
openedSquares++;
if (openedSquares >= BOARD_SIZE * BOARD_SIZE - NUMBER_OF_MINES)
{
isPlaying = false;
OnWonGame();
}

BoardSquare clickedSquare = sender as BoardSquare;
if (clickedSquare != null && clickedSquare.Value == "M")
{
isPlaying = false;
OnLostGame();
}
}
}
Basically, it keeps track of the number of squares opened so far. If that number reaches the total number of squares minus the number of mines, you've got yourself a winner. If the value of the opened square is 'M' for 'mine' - kaboom!!!!

You can tweak some settings by changing the values of the constants in the Page class:
private const int BOARD_SIZE = 7;
private const int NUMBER_OF_MINES = 8;
What these do is self-explanatory.

You can download the source code from here.

Regards,
Boyan

0 comments: