Playing Cards

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

www.cespage.com/silverlight/sl4tut11.html

Step 1

Start Microsoft Visual Web Developer 2010 Express, then Select File then New Project... Select "Visual Basic" then "Silverlight 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

New Silverlight Application window should appear, uncheck the box "Host the Silverlight Application in a new Web site" and then select the required Silverlight Version, see below:

New Silverlight Application

Step 3

A Blank Page named MainPage.xaml should then appear, see below:

MainPage.xaml

Step 4

Then from the All Silverlight Controls section in the Toolbox select the Canvas control:

Canvas Control

Step 5

Draw a Canvas that fill the whole Page or in the XAML Pane between the "<Grid>" and "</Grid>" lines type the following XAML:

<Canvas Height="300" Width="400" HorizontalAlignment="Left" VerticalAlignment="Top" Name="Page">
</Canvas>

See below:

MainPage with Canvas

Step 6

Then from the Common Silverlight Controls section in the Toolbox select the Button control:

Button Control

Step 7

Draw Three Buttons on the Canvas by dragging the Buttons from the Toolbox onto the Canvas then in the XAML Pane inbetween the "<Canvas>" and "</Canvas>" tags change the "<Button>" lines to the following:

<Button Canvas.Left="35" Canvas.Top="35" Height="160" Width="120" Name="PileOne"/>
<Button Canvas.Left="245" Canvas.Top="35" Height="160" Width="120" Name="PileTwo"/>
<Button Canvas.Left="163" Canvas.Top="263" Height="23" Width="75" Name="New" Content="New"/> 

See below:

MainPage with Canvas and Buttons

Step 8

Right Click on the Page or the entry for "MainPage.xaml" in Solution Explorer and choose the "View Code" option. In the Code View below the "Inherits UserControl" line type the following:

Private Const CLUBS As String = "♣"
Private Const DIAMONDS As String = "♦"
Private Const HEARTS As String = "♥"
Private Const SPADES As String = "♠"
Private Const ACE As String = "A"
Private Const JACK As String = "J"
Private Const QUEEN As String = "Q"
Private Const KING As String = "K"

Private _deckOne, _deckTwo As List(Of Integer)
Private _cardOne, _cardTwo As Integer
Private _first, _second As Integer
Private _score, _counter As Integer

See Below:

MainPage.xaml Declarations

Step 9

While still in the Code View for MainPage.xaml, below the "End Sub" for "Public Sub New()" Constructor type the following Function:

Private Function Pip(ByRef Content As String, ByRef Foreground As Color, _
    ByRef FontSize As Double, ByRef FontFamily As String, _
    ByRef Left As Double, ByRef Top As Double) As TextBlock
  Dim _pip As 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
End Function

See Below:

MainPage Pip Function

Step 10

While still in the Code View for MainPage.xaml, below "End Function" for "Private Function Pip(...)" Function, type the following Function:

Private Function Deck(ByRef Card As Integer, ByRef BackColor As Color) As Canvas
  Dim _card As New Canvas
  Dim _text As TextBlock = Nothing
  Dim _fore As Color = Colors.Black
  Dim _suite As String = ""
  Dim _display As String = ""
  Dim _value As String = ""
  Select Case Card
    Case 1 To 13
      _fore = Colors.Black
      _suite = CLUBS
      _display = Card
    Case 14 To 26
      _fore = Colors.Red
      _suite = DIAMONDS
      _display = Card - 13
    Case 27 To 39
      _fore = Colors.Red
      _suite = HEARTS
      _display = Card - 26
    Case 40 To 52
      _fore = Colors.Black
      _suite = SPADES
      _display = Card - 39
  End Select
  _value = _display
  _card.Width = 110
  _card.Height = 150
  _card.Background = New SolidColorBrush(BackColor)
  Select Case _value
    Case 1
      _display = ACE
      _card.Children.Add(Pip(_suite, _fore, 70, "Times New Roman", 35, 30)) ' Centre
    Case 2
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 0)) ' Middle Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 104)) ' Middle Bottom
    Case 3
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 0)) ' Middle Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 52)) ' Centre
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 104)) ' Middle Bottom
    Case 4
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 0)) ' Top Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 0)) ' Top Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 104)) ' Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 104)) ' Bottom Right
    Case 5
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 0)) ' Top Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 0)) ' Top Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 52)) ' Centre
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 104)) ' Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 104)) ' Bottom Right
    Case 6
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 0)) ' Top Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 0)) ' Top Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 52)) ' Centre Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 52)) ' Centre Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 104)) ' Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 104)) ' Bottom Right
    Case 7
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 0)) ' Top Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 0)) ' Top Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 52)) ' Centre Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 26)) ' Centre Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 52)) ' Centre Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 104)) ' Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 104)) ' Bottom Right
    Case 8
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 0)) ' Top Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 0)) ' Top Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 52)) ' Centre Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 26)) ' Centre Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 78)) ' Centre Bottom
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 52)) ' Centre Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 104)) ' Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 104)) ' Bottom Right
    Case 9
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 0)) ' Top Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 0)) ' Top Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 34)) ' Centre Left Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 70)) ' Centre Left Bottom
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 52)) ' Centre
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 34)) ' Centre Right Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 70)) ' Centre Right Bottom
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 104)) ' Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 104)) ' Bottom Right
    Case 10
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 0)) ' Top Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 0)) ' Top Right
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 34)) ' Centre Left Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 70)) ' Centre Left Bottom
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 26)) ' Centre Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 42, 78)) ' Centre Bottom
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 34)) ' Centre Right Top
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 70)) ' Centre Right Bottom
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 16, 104)) ' Bottom Left
      _card.Children.Add(Pip(_suite, _fore, 40, "Arial", 68, 104)) ' Bottom Right
    Case 11
      _display = JACK
      _card.Children.Add(Pip(_display, _fore, 70, "Times New Roman", 40, 35)) ' Centre
    Case 12
      _display = QUEEN
      _card.Children.Add(Pip(_display, _fore, 70, "Times New Roman", 30, 30)) ' Centre
    Case 13
      _display = KING
      _card.Children.Add(Pip(_display, _fore, 70, "Times New Roman", 30, 35)) ' Centre
  End Select
  If Len(_display) = 1 Then
    _card.Children.Add(Pip(_display, _fore, 16, "Times New Roman", 2, 4))
    _card.Children.Add(Pip(_display, _fore, 16, "Times New Roman", 96, 116))
  Else
    _card.Children.Add(Pip(_display, _fore, 16, "Times New Roman", 0, 4))
    _card.Children.Add(Pip(_display, _fore, 16, "Times New Roman", 93, 116))
  End If
  _card.Children.Add(Pip(_suite, _fore, 20, "Arial", 1, 16))
  _card.Children.Add(Pip(_suite, _fore, 20, "Arial", 94, 130))
  Return _card
End Function

See Below:

MainPage Deck Function

Step 11

While still in the Code View for MainPage.xaml, below the "End Function" for "Private Function Deck(...)" type the following Function and Sub:

Private Function Card(ByRef Value As Integer, ByRef IsFacing As Boolean, _
    ByRef BackColor As Color) As Canvas
  If IsFacing Then
    Return Deck(Value, BackColor)
  Else
    Dim _card As New Canvas
    _card.Width = 110
    _card.Height = 150
    _card.Background = New SolidColorBrush(BackColor)
    Return _card
  End If
End Function

Private Sub Match()
  If _cardOne < 52 And _cardTwo < 52 Then
    _first = _deckOne(_cardOne)
    PileOne.Content = Card(_first, True, Colors.White)
    _cardOne += 1
    _second = _deckTwo(_cardTwo)
    PileTwo.Content = Card(_second, True, Colors.White)
    _cardTwo += 1
    If _first Mod 13 = _second Mod 13 Then ' Ignore Suite for Match
      _score += 1
      MessageBox.Show("Match!", "Playing Cards", MessageBoxButton.OK)
    End If
    _counter += 1
  Else
    MessageBox.Show("Game Over! Matched " & _score & " out of " & _counter & " cards!", _
      "Playing Cards", MessageBoxButton.OK)
  End If
End Sub

See Below:

MainPage Card Function and Match Sub

Step 12

While still in the Code View for MainPage.xaml, below the "End Sub" for "Private Sub Match()" type the following Function:

Private Function Shuffle() As List(Of Integer)
  Dim _number As Integer
  Dim _numbers As New List(Of Integer)
  While _numbers.Count < 52 ' Select 52 Numbers
    Randomize() ' Random Number
    _number = Int((52 * Rnd()) + 1) ' Between 1 - 52
    If Not _numbers.Contains(_number) _
        Or _numbers.Count < 1 Then ' If Chosen or None
      _numbers.Add(_number) ' Add Number
    End If
  End While
  Return _numbers
End Function

See Below:

MainPage Shuffle Function

Step 13

Return to the Designer View, by selecting the "MainPage.xaml" Tab, or Right Click on the Page or the Entry for "MainPage.xaml" in Solution Explorer and choose the "View Designer" option.
Double Click on the "New" Button Control and type in the New_Click Sub:

_score = 0
PileOne.Content = Card(1, False, Colors.Red)
PileTwo.Content = Card(1, False, Colors.Blue)
_deckOne = Shuffle()
_deckTwo = Shuffle()

See Below:

New Button Click Event

Step 14

Return to the Designer View, by selecting the "MainPage.xaml" Tab, or Right Click on the Page or the Entry for "MainPage.xaml" in Solution Explorer and choose the "View Designer" option.
Double Click on the Left-most Button (PileOne) and type in the PileOne_Click Sub:

If Not PileOne.Content Is Nothing Then
    Match()
End If

See Below:

PileOne Button Click Event

Step 15

Return to the Designer View, by selecting the "MainPage.xaml" Tab, or Right Click on the Page or the Entry for "MainPage.xaml" in Solution Explorer and choose the "View Designer" option.
Double Click on the Right-most Button (PileTwo) and type in the PileTwo_Click Sub:

If Not PileTwo.Content Is Nothing Then
    Match()
End If

See Below:

PileTwo Button Click Event

Step 16

Save the Project as you have now finished the Silverlight application. Select Debug then Start Debugging or click on Start Debugging:

Start Debugging

After you do, the following will appear in a new Web Browser window:

Application Running

Step 17

Click on the New Button and the following will appear:

New Game

Step 18

Click on either of the two 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 19

Close the Browser window by clicking on the Close Button Close on the top right of the Web Browser to Stop the application.

This is a very simple game using the standard deck of 52 playing cards - try using this as a basis for your own more complex card games such as 21 or Poker, or make them look mroe like cards, it is up to you!