UbGames

How to Shuffle a Deck of Cards in C#

shuffling a deck

How to Shuffle a Deck of Cards in C#

In this tutorial you will build an array to learn how to shuffle a deck of cards using a C# Windows Form project. The program will step you through the process loading, shuffling, and displaying the deck of cards, using an array and the Fisher-Yates shuffling algorithm. The program will include functions to hide and show the face cards.

array of cards

Install Visual Studio IDE

If you have not installed Visual Studio 2022, please read our article on How to Install Visual Studio.

Create a new Windows Forms App with Visual Studio

If you are not sure how to create a new Windows Forms project in C#, please read our article on How to Create a C# Project in Visual Studio.

ArrayShuffling Project File and Folder Structure

You will need to copy the card images into a folder called “Cards” inside the bin folder. It is recommended to create your project first, then copy the Cards folder to the “Bin” folder.

Download the Cards.zip file to the project folder, for example “ArrayShuffling”.

Once you create your new project you should have something like the following:

play cards

This project will use the default form “Form1” to display the controls and add the game logic.

Resize Form1 by changing the size of the form to 1050×550. Changing the form size will fit the array of images on the form.

Setting up the Form1.cs design file

You will need to add four buttons to Form1 and set the properties for each button.

add buttons

How-to add a button to the form:

Click on the View>Toolbox in the Menu bar. Under “All Windows Forms”, select the button control, then drag & drop the button onto the Form1 window.

Next, change the properties for each of the four buttons.

properties

Click on the button control to view the property settings. Change the following properties for each of the four buttons:

BUTTON1:

Name:              DealCards

Text:                Shuffle && Deal Cards

Enable:            True

Click event:     DealCards_Click

BUTTON2:

Name:              ResetCards

Text:                Reset Cards

Enable:            True

Click event:     ResetCards_Click

BUTTON3:

Name:              ShowCards

Text:                Show Cards

Enable:            False

Click event:     ShowCards_Click

BUTTON4:

Name:              HideCards

Text:                Hide Cards

Enable:            False

Click event:     HideCards_Click

Note: To add the Click event, click on the lightening button on the Properties menu bar.

Next, open the code window and add the following code to Form1.cs.

view code

Create an array of PictureBox objects and set the Cards folder path

Add the PictureBox variables, then set the variables to an array. Add card width and height variables, and set the Path to the location of the card images used in the project.

using System;

using System.Drawing;

using System.Windows.Forms;

namespace ArrayShuffling

{

    public partial class Form1 : Form

    {

        private const int MAXCARDS = 52;

        //Create an array of PictureBoxes

        private PictureBox[] cards;

        private PictureBox[] cardsback;

        //the on-screen width of each card sized to fit the window

        private float displayCardWidth = 0;

        //the on-screen height of each card sized to fit the window

        private float displayCardHeight = 0;

        //get width of card graphics

        private int cardWidth = 75;

        //get height of card graphics

        private int cardHeight = 100;

        //space between cards

        private float cardMargin = 2;

        //number of vertical cards

        const int maxCardsHeight = 4;

        //number of horizontal cards

        const int maxCardsWidth = 13;

        //the @ will allow us the use of single slashes instead of using double slashes.

        //the path is set to the Cards folder under the bin folder.

        public const string cardsPath = @”Cards\”;

        public Form1()

        {

            InitializeComponent();

            //Assign the cards and cardsback to an array sequence value of 52 elements

            cards = new PictureBox[MAXCARDS];

            cardsback = new PictureBox[MAXCARDS];

            //set card height and width

            displayCardHeight = cardHeight;

            displayCardWidth = cardWidth;

        }

Form1 Load, ResetCards Click

The Form1 Load and ResetCards Click events will create each object, populate the images, then display the images as an unshuffled deck of cards.

  • CreateControls() Method will create 52 PictureBoxes. Set the PictureBox properties width and height for each card image.
  • DisplayControls() Method will display 52 cards. Set the distance in pixels between the left edge of the control and the left edge of its container. Adjust control placement from the top of the form. Add the PictureBoxes to the control one by one. Set the location of each PictureBox.

private void Form1_Load(object sender, EventArgs e)

{

    //show unsorted deck of cards, when program starts

    CreateControls();

    DisplayControls();

}

private void ResetCards_Click(object sender, EventArgs e)

{

    //reset deck of cards to unshuffled display

    CreateControls();

    DisplayControls();

}

DealCards Click

The DealCards Click event creates each object, populates the images, then displays the images as a shuffled deck of cards.

  • CreateControls() Method will create 52 PictureBoxes. Set the PictureBox properties width and height for each card image.
  • DisposeControls() Method will cleanup and release the control from memory.
  • SizeImage() Method will assign the card image to each element in the array.
  • ShuffleCards() Method that is using the Fisher-Yates shuffle algorithm.
  • DisplayControls() Method will display 52 cards. Set the distance in pixels between the left edge of the control and the left edge of its container. Adjust control placement from the top of the form. Add the PictureBoxes to the control one by one. Set the location of each PictureBox.

private void DealCards_Click(object sender, EventArgs e)

{

    // check to see if ShowCards button is enabled

    if (ShowCards.Enabled == true)

        ShowCards.Enabled = false;

    // methods that control different parts of the game’s functionality

    CreateControls();

    ShuffleCards();

    DisplayControls();

    // hidecards button will be usable

    HideCards.Enabled = true;

}

private void CreateControls()

{

    // check to see if cards are null

    if (cards[0] != null)

    DisposeControls();

    byte i = 0;

    for (byte y = 0; y <= 3; y++)

    {

        for (byte x = 0; x <= 12; x++)

        {

            var newPictureBox = new PictureBox();

            // set the width of the card image

            newPictureBox.Width = cardWidth;

            // set the height of the card image

            newPictureBox.Height = cardHeight;

            // send over the index of the array and return of the image of the card for each index

            cards[i] = SizeImage(newPictureBox, i + 1);

            i += 1;

        }

    }

}

private void DisposeControls()

{

    foreach (var c in cards)

    {

        // dispose the control

        c.Dispose();

    }

}

private PictureBox SizeImage(PictureBox c, int i)

{

    // the file path, index number of array and string which is the image exetension

    c.Image = Image.FromFile(cardsPath + i.ToString() + “.png”);

    // stretchimage image to fix the size of the picturebox

    c.SizeMode = PictureBoxSizeMode.StretchImage;

    // return the card images

    return c;

}

 private void ShuffleCards()

 {

    //Fisher-Yates shuffle algorithm

    int i = 0;

    int j = 0;

    int MAXCARDS = 52;

    Random sortRandom = new Random();

    for (i = 0; i <= (MAXCARDS – 1); i++)

    {

        j = Convert.ToInt32(sortRandom.Next(0, i + 1));

        var deck = cards[i];

        cards[i] = cards[j];

        cards[j] = deck;

    }

}

private void DisplayControls()

{

    //horizontal space between cards

    float xoffset = cardMargin;

    //vertical space between cards

    float yoffset = cardMargin;

    byte i = 0;

    for (byte y = 0; y <= 3; y++)

    {

        for (byte x = 0; x <= 12; x++)

        {

            // set the distance in pixels between the left edge of the

            // control and the left edge of its container

            cards[i].Left = (i * 20) + 100;

            // adjust control placement from the top of the form

            cards[i].Top = 75;

            // add the PictureBoxes to the control one by one. 1.png, 2.png, etc…

            this.Controls.Add(cards[i]);

            // bring the control to the front

            cards[i].BringToFront();

            cards[i].Location = new Point(Convert.ToInt32(x * (displayCardWidth + cardMargin) + xoffset), Convert.ToInt32(y * (displayCardHeight + cardMargin) + yoffset));

            i += 1;

        }

    }

}

HideCards Click

The HideCards Click event creates each object, populates the images, and then displays an image card as the back of a card.

  • CreateControlsBack() Method will create 52 PictureBoxes. Set the PictureBox properties width and height for each back of card image.
  • SizeImageBack() Method will assign the cardsback image to each element in the array.
  • DisplayControlsBack() Method will display 52 card backs. Set the distance in pixels between the left edge of the control and the left edge of its container. Adjust control placement from the top of the form. Add the PictureBoxes to the control one by one displaying the back.png

private void HideCards_Click(object sender, EventArgs e)

{

    // methods that control different parts of the game’s functionality

    CreateControlsBack();

    DisplayControlsBack();

    // showcards button will be usable

    ShowCards.Enabled = true;

    // hidecards button will not be usable

    HideCards.Enabled = false;

}

private void CreateControlsBack()

{

    byte i = 0;

    for (byte y = 0; y <= 3; y++)

    {

        for (byte x = 0; x <= 12; x++)

        {

            var newPictureBox = new PictureBox();

            // set the width of the card image

            newPictureBox.Width = cardWidth;

            // set the height of the card image

            newPictureBox.Height = cardHeight;

            // send over the index of the array and return of the image of the card for each index

            cardsback[i] = SizeImageBack(newPictureBox, i + 1);

            i += 1;

        }

    }

}

private PictureBox SizeImageBack(PictureBox c, int i)

{

    // the file path, index number of array and string which is the back image

    c.Image = Image.FromFile(cardsPath + “back.png”);

    // stretchimage image to fix the size of the picturebox

    c.SizeMode = PictureBoxSizeMode.StretchImage;

    // return the card images

    return c;

}

private void DisplayControlsBack()

{

    //horizontal space between cards

    float xoffset = cardMargin;

    //vertical space between cards

    float yoffset = cardMargin;

    byte i = 0;

    for (byte y = 0; y <= 3; y++)

    {

        for (byte x = 0; x <= 12; x++)

        {

            // set the distance in pixels between the left edge of the

            // control and the left edge of its container

            cardsback[i].Left = (i * 20) + 100;

            // adjust control placement from the top of the form

            cardsback[i].Top = 75;

            // add the PictureBoxes to the control all 52 images of the back.png

            this.Controls.Add(cardsback[i]);

            // bring the control to the front             

            cardsback[i].BringToFront();

            cardsback[i].Location = new Point(Convert.ToInt32(x * (displayCardWidth + cardMargin) + xoffset), Convert.ToInt32(y * (displayCardHeight + cardMargin) + yoffset));

            i += 1;

        }

    }

}

ShowCards Click

The ShowCards Click event creates each object, populates the images, calls the DisplayControls() Method which displays the current state of the cards.

private void ShowCards_Click(object sender, EventArgs e)

{

    // method that control different parts of the game’s functionality

    DisplayControls();

    // hidecards button will be usable

    HideCards.Enabled = true;

    // showcards button will not be usable

    ShowCards.Enabled = false;

}

The program will load and display 52 cards as an unshuffled deck. When the “Shuffle & Deal Cards” button is clicked the cards will be displayed as a shuffled deck.

There are two other buttons. The “Hide” button, which will hide the face of the cards by displaying images as the back of cards. The other is the “Show” button, which will show the face of the cards.

Run Project with Visual Studio 2022

Visual Studio will build your project by converting the source code into an executable (.exe file)

  • To build the project, choose Build Solution from the Build menu.
  • To run the code, on the menu bar, choose Debug > Start Debugging. You can also run the code, with hotkeys, Press Ctrl + F5.

ArrayShuffling

The first screen will represent an unsorted (unshuffled) display of 52 cards.

card faces

Clicking the “Shuffle & Deal” button will change the layout to represent a sorted (Shuffled) display of 52 cards.

array of cards

Clicking the “Hide” button will change the layout to display images to hide the face of the cards.

card backs

Clicking the “Show” button will display the face cards.

You can download the C# Source Code for the Shuffling and Dealing Cards project.

Conclusion:

C# is one of the most modern and versatile programming languages for numerous projects. Learning this language will provide you with skills to advanced game programming.

ubgames

How to Shuffle a Deck of Cards in C#