Playing Cards

Playing Cards is a simple card matching using the standard 52 playing cards with all four suites; Spades, Clubs, Diamonds and Hearts using Silverlight on Windows Phone 7.

www.cespage.com/silverlight/wp7tut11.html

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:

New Project

Step 2

A Windows Phone application Page named MainPage.xaml should then appear, see below:

MainPage.xaml

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="300"/>
    <RowDefinition Height="*"/>
    <RowDefinition Height="Auto"/>
  </Grid.RowDefinitions>
  <Grid Grid.Row="0" x:Name="Header">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="220"/>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="220"/>
    </Grid.ColumnDefinitions>
    <!-- Header -->
  </Grid>
  <!-- Footer -->
  <Button Grid.Row="2" Width="160" Content="new" Click="New_Click"/>
</Grid>

XAML:

MainPage XAML View

Design:

MainPage Design View

Step 4

Then from the Windows Phone Controls section in the Toolbox select the Button control:

Button Control

Step 5

Draw Two Buttons on the "Header" section of the Grid, the large section below "Page Title", by dragging the buttons onto the Top part of the Grid, then in the XAML Pane below <!-- Header -->, change the "Button" lines to the following:

<Button Grid.Column="0" Name="PileOne" Click="PileOne_Click"/>
<Button Grid.Column="2" Name="PileTwo" Click="PileTwo_Click"/>

See Below:

MainPage with Buttons

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 "public MainPage()" type the following declarations:

const string CLUBS = "♣";
const string DIAMONDS = "♦";
const string HEARTS = "♥";
const string SPADES = "♠";
const string ACE = "A";
const string JACK = "J";
const string QUEEN = "Q";
const string KING = "K";

private List<int> _deckOne = new List<int>();
private List<int> _deckTwo = new List<int>();
private int _cardOne, _cardTwo;
private int _first, _second;
private int _score, _counter;

See Below:

MainPage Declarations

Step 7

While still the Code View for MainPage.xaml.cs above "public MainPage()" type the following Method:

private TextBlock Pip(string Content, Color Foreground, 
double FontSize, string FontFamily, double Left, double Top)
{
  TextBlock _pip = new TextBlock();
  _pip.FontSize = FontSize;
  _pip.FontFamily = new FontFamily(FontFamily);
  _pip.Text = Content;
  _pip.Foreground = new SolidColorBrush(Foreground);
  _pip.SetValue(Canvas.LeftProperty, Left);
  _pip.SetValue(Canvas.TopProperty, Top);
  return _pip;
}

See Below:

MainPage Pip Method

Step 8

While still the Code View for MainPage.xaml.cs, below the "}" of the "private TextBlock Pip(...)" method type the following Method:

private Canvas Deck(ref int Card, ref Color BackColor)
{
  Canvas _card = new Canvas();
  Color _fore = Colors.Black;
  string _suite = "";
  string _display = "";
  int _value;
  if (Card >= 1 && Card <= 13)
  {
    _fore = Colors.Black;
    _suite = CLUBS;
    _display = Card.ToString();
  }
  else if (Card >= 14 && Card <= 26)
  {
    _fore = Colors.Red;
    _suite = DIAMONDS;
    _display = (Card - 13).ToString();
  }
  else if (Card >= 27 && Card <= 39)
  {
    _fore = Colors.Red;
    _suite = HEARTS;
    _display = (Card - 26).ToString();
  }
  else if (Card >= 40 && Card <= 52)
  {
    _fore = Colors.Black;
    _suite = SPADES;
    _display = (Card - 39).ToString();
  }
  _value = int.Parse(_display);
  _card.Width = 170;
  _card.Height = 250;
  _card.Background = new SolidColorBrush(BackColor);
  switch (_value)
  {
    case 1:
      _display = ACE;
      _card.Children.Add(Pip(_suite, _fore, 100, "Times New Roman", 50, 60)); // Centre
      break;
    case 2:
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 20)); // Middle Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 160)); // Middle Bottom
      break;                                
    case 3:                                   
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 20)); // Middle Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 90)); // Centre
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 160)); // Middle Bottom
      break;                                
    case 4:                                   
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 20)); // Top Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 20)); // Top Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 160)); // Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 160)); // Bottom Right
      break;                                
    case 5:                                   
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 20)); // Top Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 20)); // Top Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 90)); // Centre
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 160)); // Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 160)); // Bottom Right
      break;                                
    case 6:                                   
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 20)); // Top Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 20)); // Top Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 90)); // Centre Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 90)); // Centre Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 160)); // Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 160)); // Bottom Right
      break;                                
    case 7:                                   
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 20)); // Top Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 20)); // Top Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 90)); // Centre Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 55)); // Centre Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 90)); // Centre Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 160)); // Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 160)); // Bottom Right
      break;                                
    case 8:                                   
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 20)); // Top Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 20)); // Top Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 90)); // Centre Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 55)); // Centre Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 125)); // Centre Bottom
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 90)); // Centre Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 160)); // Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 160)); // Bottom Right
      break;                                
    case 9:                                   
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 20)); // Top Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 20)); // Top Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 65)); // Centre Left Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 110)); // Centre Left Bottom
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 90)); // Centre
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 65)); // Centre Right Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 110)); // Centre Right Bottom
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 160)); // Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 160)); // Bottom Right
      break;                                
    case 10:                                  
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 20)); // Top Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 20)); // Top Right
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 65)); // Centre Left Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 110)); // Centre Left Bottom
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 55)); // Centre Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 65, 125)); // Centre Bottom
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 65)); // Centre Right Top
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 110)); // Centre Right Bottom
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 20, 160)); // Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 60, "Arial", 110, 160)); // Bottom Right
      break;
    case 11:
      _display = JACK;
      _card.Children.Add(Pip(_display, _fore, 100, "Times New Roman", 65, 65)); // Centre
      break;
    case 12:
      _display = QUEEN;
      _card.Children.Add(Pip(_display, _fore, 100, "Times New Roman", 50, 65)); // Centre
      break;
    case 13:
      _display = KING;
      _card.Children.Add(Pip(_display, _fore, 100, "Times New Roman", 50, 65)); // Centre
      break;
  }
  if ((_display.Length == 1))
  {
    _card.Children.Add(Pip(_display, _fore, 20, "Times New Roman", 10, 4));
    _card.Children.Add(Pip(_display, _fore, 20, "Times New Roman", 150, 204));
  }
  else
  {
    _card.Children.Add(Pip(_display, _fore, 20, "Times New Roman", 5, 4));
    _card.Children.Add(Pip(_display, _fore, 20, "Times New Roman", 145, 204));
  }
  _card.Children.Add(Pip(_suite, _fore, 30, "Arial", 7, 16));
  _card.Children.Add(Pip(_suite, _fore, 30, "Arial", 145, 215));
  return _card;
}

See Below:

MainPage Deck Method

Step 9

While still the Code View for MainPage.xaml.cs, below the "}" of the "private Canvas Deck(...)" method type the following Methods:

private Canvas Card(int Value, bool IsFacing, Color BackColor)
{
  if (IsFacing)
  {
    return Deck(ref Value, ref BackColor);
  }
  else
  {
    Canvas _card = new Canvas();
    _card.Width = 170;
    _card.Height = 250;
    _card.Background = new SolidColorBrush(BackColor);
    return _card;
  }
}

private void Match()
{
  if ((_cardOne < 52) && (_cardTwo < 52))
  {
    _first = _deckOne[_cardOne];
    PileOne.Content = Card(_first, true, Colors.White);
    _cardOne++;
    _second = _deckTwo[_cardTwo];
    PileTwo.Content = Card(_second, true, Colors.White);
    _cardTwo++;
    if ((_first % 13) == (_second % 13)) // Ignore Suite for Match
    {
      _score++;
      MessageBox.Show("Match!", "Playing Cards", MessageBoxButton.OK);
    }
    _counter++;
  }
  else
  {
    MessageBox.Show("Game Over! Matched " + _score + " out of " +
    _counter + " cards!", "Playing Cards", MessageBoxButton.OK);
  }
}

See Below:

MainPage Card and Match Method

Step 10

While still the Code View for MainPage.xaml.cs, below the "}" of the "private void Match()" method type the following Methods:

private List<int> Shuffle()
{
  int number;
  List<int> _numbers = new List<int>();
  Random random = new Random();
  while ((_numbers.Count < 52)) // Select 52 Numbers
  {
    number = random.Next(1, 53); // Seeded Random Number
    if ((!_numbers.Contains(number)) || (_numbers.Count < 1))
    {
      _numbers.Add(number); // Add if number Chosen or None
    }
  }
  return _numbers;
}

See Below:

MainPage Shuffle Method

Step 11

While still the Code View for MainPage.xaml.cs, below the "}" of the "public MainPage()" method type the following Event Handlers:

private void New_Click(object sender, RoutedEventArgs e)
{
  _score = 0;
  PileOne.Content = Card(1, false, Colors.Red);
  PileTwo.Content = Card(1, false, Colors.Blue);
  _deckOne = Shuffle();
  _deckTwo = Shuffle();
}

private void PileOne_Click(object sender, RoutedEventArgs e)
{
  if (PileOne.Content != null)
  {
    Match();
  }
}

private void PileTwo_Click(object sender, RoutedEventArgs e)
{
  if (PileTwo.Content != null)
  {
    Match();
  }
}

See Below:

MainPage Event Handlers

Step 12

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:

Start Debugging

After you do, the following will appear in the Windows Phone Emulator after it has been loaded:

Application Running

Step 13

Tap the "new" Button and the following will appear:

New

Step 14

Tap on either two of the Buttons to show a Card, match two to score a point, do this until all the cards have been displayed, see below:

Playing Cards

Step 15

You can then Stop the application by selecting the Visual Studio 2010 application window and clicking on the Stop Debugging button:

Stop Debugging

This is a very simple game using the standard 52 playing cards deck, try using this as a basis for your own more complex games such as 21 or Poker - make it your own!