Memory Game is a simple shape matching game that can be created using Silverlight on Windows Phone 7.
Printer Friendly Download Tutorial (629KB) Download Source Code (17.6KB)
Step 1
Start Microsoft Visual Studio 2010 Express for Windows Phone, then Select File then New Project... Select "Visual C#" then "Silverlight for Windows Phone" and then "Windows Phone Application" from Templates, select a Location if you wish, then enter a name for the Project and then click OK, see below:
Step 2
A Windows Phone application Page named MainPage.xaml should then appear, see below:
Step 3
In the XAML Pane for MainPage.xaml between the <Grid x:Name="ContentGrid" Grid.Row="1"> and </Grid> lines, enter the following XAML:
<Grid x:Name="ContentMain">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Grid.Row="1" Width="160" Content="new" Click="New_Click"/>
</Grid>
XAML:
Design:
Step 4
Then from the Windows Phone Controls section in the Toolbox select the Grid control:
Step 5
Draw a Grid on the Page by dragging a Grid from the Toolbox onto the middle part of the Grid on the Page, then in the XAML Pane change the "grid1" line to the following:
<Grid Height="400" Width="400" Name="Display"/>
See below:
Step 6
Right Click on the Page or the entry for "MainPage.xaml" in Solution Explorer and choose the "View Code" option. In the Code View above "namespace MemoryGame" type the following:
using System.Windows.Threading;
Also in the CodeView above "public MainPage()" type the following declarations:
int _moves = 0; int _first = 0; int _second = 0; Button _firstButton; Button _secondButton; int[,] _board = new int[4,4]; List<int> _matches = new List<int>(); DispatcherTimer _timer = new DispatcherTimer();
See Below:
Step 7
While still the Code View for MainPage.xaml.cs above "public MainPage()" type the following Method:
private object Shape(ref System.Windows.Media.PointCollection Points) { Polygon _shape = new Polygon(); _shape.Stretch = Stretch.Uniform; _shape.StrokeLineJoin = PenLineJoin.Round; _shape.Points = Points; _shape.Height = 40; _shape.Width = _shape.Height; _shape.Stroke = new SolidColorBrush((Color) App.Current.Resources["PhoneForegroundColor"]); _shape.StrokeThickness = 5; _shape.Margin = new Thickness(4); return _shape; }
See Below:
Step 8
While still the Code View for MainPage.xaml.cs, below the "}" of the "private object Shape(...)" method type the following Method:
private object Card(ref int Type) { System.Windows.Media.PointCollection _points = new System.Windows.Media.PointCollection(); switch (Type) { case 1: // Circle EllipseGeometry _ellipse = new EllipseGeometry(); Path _circle = new Path(); _ellipse.Center = new Point(20, 20); _ellipse.RadiusX = 20; _ellipse.RadiusY = 20; _circle.Data = _ellipse; _circle.Stroke = new SolidColorBrush((Color) App.Current.Resources["PhoneForegroundColor"]); _circle.StrokeThickness = 4; _circle.Margin = new Thickness(4); return _circle; case 2: // Cross Path _lines = new Path(); LineGeometry _line1 = new LineGeometry(); LineGeometry _line2 = new LineGeometry(); GeometryGroup _linegroup = new GeometryGroup(); _line1.StartPoint = new Point(0, 0); _line1.EndPoint = new Point(40, 40); _line2.StartPoint = new Point(40, 0); _line2.EndPoint = new Point(0, 40); _linegroup.Children.Add(_line1); _linegroup.Children.Add(_line2); _lines.Data = _linegroup; _lines.Stroke = new SolidColorBrush((Color) App.Current.Resources["PhoneForegroundColor"]); _lines.StrokeThickness = 4; _lines.Margin = new Thickness(4); return _lines; case 3: // Triangle _points.Add(new Point(150, 0)); _points.Add(new Point(0, 250)); _points.Add(new Point(300, 250)); return Shape(ref _points); case 4: // Square _points.Add(new Point(0, 0)); _points.Add(new Point(0, 100)); _points.Add(new Point(100, 100)); _points.Add(new Point(100, 0)); return Shape(ref _points); case 5: // Pentagon _points.Add(new Point(0, 125)); _points.Add(new Point(150, 0)); _points.Add(new Point(300, 125)); _points.Add(new Point(250, 300)); _points.Add(new Point(50, 300)); return Shape(ref _points); case 6: // Hexagon _points.Add(new Point(75, 0)); _points.Add(new Point(225, 0)); _points.Add(new Point(300, 150)); _points.Add(new Point(225, 300)); _points.Add(new Point(75, 300)); _points.Add(new Point(0, 150)); return Shape(ref _points); case 7: // Star _points.Add(new Point(9, 2)); _points.Add(new Point(11, 7)); _points.Add(new Point(17, 7)); _points.Add(new Point(12, 10)); _points.Add(new Point(14, 15)); _points.Add(new Point(9, 12)); _points.Add(new Point(4, 15)); _points.Add(new Point(6, 10)); _points.Add(new Point(1, 7)); _points.Add(new Point(7, 7)); return Shape(ref _points); case 8: // Rhombus _points.Add(new Point(50, 0)); _points.Add(new Point(100, 50)); _points.Add(new Point(50, 100)); _points.Add(new Point(0, 50)); return Shape(ref _points); default: return Type; } }
See Below:
Step 9
While still the Code View for MainPage.xaml.cs, below the "}" of the "private object Card(...)" method type the following Method and Button Event Handler:
private void Clear(object sender, EventArgs e) { if (!(_firstButton == null)) { _firstButton.Content = null; _firstButton = null; } if (!(_secondButton == null)) { _secondButton.Content = null; _secondButton = null; } _timer.Stop(); } private void Button_Click(object sender, System.Windows.RoutedEventArgs e) { Button _btn = new Button(); int _row; int _col; int _selected; if (!_timer.IsEnabled) { _btn = ((Button)(sender)); _row = (int)_btn.GetValue(Grid.RowProperty); _col = (int)_btn.GetValue(Grid.ColumnProperty); _selected = _board[_row, _col]; if ((_matches.IndexOf(_selected) < 0)) { if ((_first == 0)) // No Match { _firstButton = _btn; _first = _selected; _firstButton.Content = Card(ref _selected); } else if ((_second == 0)) { _secondButton = _btn; if (!_firstButton.Equals(_secondButton)) // Different { _second = _selected; _secondButton.Content = Card(ref _selected); if ((_first == _second)) // Is Match { _matches.Add(_first); _matches.Add(_second); MessageBox.Show("Match!", "Memory Game", MessageBoxButton.OK); if ((_matches.Count == 16)) { MessageBox.Show(("Well Done! You matched them all in " + (_moves + " moves!")), "Memory Game", MessageBoxButton.OK); } } else // No Match { _timer.Interval = TimeSpan.FromSeconds(1.5); _timer.Tick += Clear; // Clear Buttons after 1.5 Seconds _timer.Start(); } _moves++; _first = 0; _second = 0; } } } } }
See Below:
Step 10
While still the Code View for MainPage.xaml.cs, below the "}" of the "private void Button_Click(...)" method type the following Methods:
private void Add(ref Grid Grid, int Row, int Column) { Button _btn = new Button(); _btn.Click += Button_Click; _btn.Content = null; _btn.Margin = new Thickness(0); _btn.SetValue(Grid.ColumnProperty, Column); _btn.SetValue(Grid.RowProperty, Row); Grid.Children.Add(_btn); } private void Layout(ref Grid Grid) { Grid.Children.Clear(); Grid.ColumnDefinitions.Clear(); Grid.RowDefinitions.Clear(); // Setup 4x4 Grid for (int Index = 0; (Index <= 3); Index++) { Grid.RowDefinitions.Add(new RowDefinition()); Grid.ColumnDefinitions.Add(new ColumnDefinition()); } Add(ref Grid, 0, 0); Add(ref Grid, 0, 1); Add(ref Grid, 0, 2); Add(ref Grid, 0, 3); Add(ref Grid, 1, 0); Add(ref Grid, 1, 1); Add(ref Grid, 1, 2); Add(ref Grid, 1, 3); Add(ref Grid, 2, 0); Add(ref Grid, 2, 1); Add(ref Grid, 2, 2); Add(ref Grid, 2, 3); Add(ref Grid, 3, 0); Add(ref Grid, 3, 1); Add(ref Grid, 3, 2); Add(ref Grid, 3, 3); }
See Below:
Step 11
While still the Code View for MainPage.xaml.cs, below the "}" of the "private void Layout(...)" method type the following Methods:
private List<int> Random(int start, int finish, int total) { int _number; List<int> _numbers = new List<int>(); Random random = new Random(); while ((_numbers.Count < total)) // Select Numbers { // Random Number between Start and Finish _number = random.Next(start, finish + 1); if ((!_numbers.Contains(_number)) || (_numbers.Count < 1)) { _numbers.Add(_number); // Add if number Chosen or None } } return _numbers; } private void Choose() { List<int> _values = new List<int>(); List<int> _indices = new List<int>(); int _counter = 0; while (_values.Count < 17) { List<int> _numbers = Random(1, 8, 8); // Random 1 - 8 for (int _number = 0; (_number <= 7); _number++) { _values.Add(_numbers[_number]); // Add to Cards } } _indices = Random(1, 16, 16); // Random 1 - 16 for (int Column = 0; (Column <= 3); Column++) // Board Columns { for (int Row = 0; (Row <= 3); Row++) // Board Rows { _board[Column, Row] = _values[_indices[_counter] - 1]; _counter++; } } }
See Below:
Step 12
While still the Code View for MainPage.xaml.cs, below the "}" of the "public MainPage()" method type the following Event Handler:
private void New_Click(object sender, RoutedEventArgs e) { _moves = 0; _matches.Clear(); Layout(ref Display); Choose(); }
See Below:
Step 13
Save the Project as you have now finished the Windows Phone Silverlight application. Select the Windows Phone Emulator option then Select Debug then Start Debugging or click on Start Debugging:
After you do, the following will appear in the Windows Phone Emulator after it has been loaded:
Step 14
Tap the "new" Button, then Tap on any two of the Buttons shown to display a Shape, match the shapes to make a pair, do this until all are matched to win, see below:
Step 15
You can then Stop the application by selecting the Visual Studio 2010 application window and clicking on the Stop Debugging button:
This is a very simple game using Shapes for each of the Cards displayed, try changing it to use different shapes, colours or even patterns, you could even make them look more like cards - make it your own!