The Basic Outline of Functionality
- Choose the difficulty mode to play in.
- Clear default picture values used in development.
- Set the board up based on the difficulty mode.
- Get personal photos from the phone.
- Shuffle photos and select appropriate number based on difficulty mode.
- Create pairs and shuffle all cards/photos.
- Display unturned cards and any already matched photos.
- Choose card and determine matches.
- Track number of moves and time.
- Display winner once all cards are matched.

The Game Board (XAML)
The game board is basically a grid with several cells to hold the gradient cards or overturned photos. At the bottom, I keep track of number of moves and time expired.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<toolkit:WrapPanel Grid.Row="0" x:Name="LayoutPanel" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Image Source="Images/1.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/2.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/3.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/6.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/4.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/1.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/2.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/7.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/8.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/5.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/9.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/3.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/4.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/6.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/7.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/8.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/9.jpg" Width="150" Margin="5"></Image>
<Image Source="Images/5.jpg" Width="150" Margin="5"></Image>
</toolkit:WrapPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock Text="Moves:"></TextBlock>
<TextBlock x:Name="MovesLabel" Foreground="Yellow" Text="0" Margin="10,0,0,0"></TextBlock>
<TextBlock Text="Time:" Margin="50,0,0,0"></TextBlock>
<TextBlock x:Name="TimeLabel" Foreground="Yellow" Text="0 seconds" Margin="10,0,0,0"></TextBlock>
</StackPanel>
</Grid>

Highlighting a Few Areas of Development
Get Photos
A large part of the charm in this simple application is that it uses your own photos as the cards to match. I had pictures of my daughter and some wildlife we had taken while on a hiking trip (as well as some stock images that came with Windows 7) in my phone when I developed this app. Below is code to retrieve the photos from your phone – stored in MediaLibrary.
private List GetPhotos()
{
//Get photos from phone
List photos = new List();
var library = new MediaLibrary();
var pics = library.Pictures.ToArray();
//Shuffle user pics
pics.Shuffle();
//Loop through photos and add to game collection
foreach (var pic in pics)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(pic.GetThumbnail());
photos.Add(bmp);
}
//Check if enough photos are available
if (photos.Count < _tileCount / 2)
{
//Setting default images if user does not have enough pictures of their own
photos.Add(new BitmapImage(new Uri("Images/1.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/2.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/3.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/4.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/5.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/6.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/7.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/8.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/9.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/10.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/11.jpg", UriKind.Relative)));
photos.Add(new BitmapImage(new Uri("Images/12.jpg", UriKind.Relative)));
//Shuffle newly added photos as well
photos.Shuffle();
}
return photos;
}
Display Cards
This is the initial generation of the cards (gradients) and their corresponding actions once a user clicks on them.
private void DisplayCards()
{
foreach (var card in _collection.Cards)
{
var rect = new System.Windows.Shapes.Rectangle()
{
Fill = new LinearGradientBrush(new GradientStopCollection()
{
new GradientStop()
{
Color = "#FF003366".ToColor(),
Offset = 0
},
new GradientStop()
{
Color = "#FF208FFF".ToColor(),
Offset = 1
},
}, 45
)
{
MappingMode = BrushMappingMode.RelativeToBoundingBox
},
Height = _cardHeight,
Margin = new Thickness(_margin),
Name = string.Format("rect_{0}", card.ID),
Stroke = new SolidColorBrush(Colors.White),
StrokeThickness = 2,
Width = _cardWidth,
Visibility = System.Windows.Visibility.Visible
};
rect.MouseLeftButtonUp += new MouseButtonEventHandler(ChooseCard);
LayoutPanel.Children.Add(rect);
var img = new Image()
{
Height = _cardHeight,
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
Margin = new Thickness(_margin),
Name = string.Format("card_{0}", card.ID),
Source = card.Bitmap,
Width = _cardWidth,
VerticalAlignment = System.Windows.VerticalAlignment.Stretch,
Visibility = System.Windows.Visibility.Collapsed
};
LayoutPanel.Children.Add(img);
}
}
Play a SoundEffect
This code snippet is all over the place on the internet and WP7 forums, but I thought I would include it here for completeness. In PhotoMemory, I play sound effects both in match and non-match scenarios and at the end when all cards are matched for a fun little “triumph”.
//Play failure sound
var snd = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds/failed.wav"));
snd.Play();
Navigate to Another Page
Again, another simple snippet but this simply shows a way to navigate to another page within WP7 Silverlight.
this.NavigationService.Navigate(new Uri("/Game.xaml?mode=" + mode, UriKind.Relative));
Create and Use a DispatchTimer
Timers are very important in game/mobile development and using a DispatchTimer appears to be the simplest way to do it. Here I create a timer, set some variables such as the duration and what eventhandler to call, and then start the timer. After the timer has expired, the event is raised and I reset the flipped cards.
DispatcherTimer _cardTimer;
//Need to pause for 1 second before flipping back
_cardTimer = new DispatcherTimer();
_cardTimer.Interval = TimeSpan.FromSeconds(1);
_cardTimer.Tick += new EventHandler(FinishStudyingCards);
_cardTimer.Start();
void FinishStudyingCards(object sender, EventArgs e)
{
//Stop timer
_cardTimer.Stop();
//Flip cards back down after finished viewing
FlipCard(_firstCard, FlipDirection.Down);
FlipCard(_secondCard, FlipDirection.Down);
//Allow user to try again
_firstCard = null;
_secondCard = null;
_lock = false;
}

Submission
I would like to have a link to the application on Zune, however, because of complications with Microsoft my submission is still pending after more than a month. You can bet I will be writing a post on the submission process as well. Good luck, and have fun developing WP7 apps of your own!