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.
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”.
DeckOfCards1
Once you create your new project you should have something like the following:
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.
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.
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.
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.
Clicking the “Shuffle & Deal” button will change the layout to represent a sorted (Shuffled) display of 52 cards.
Clicking the “Hide” button will change the layout to display images to hide the face of the cards.
Clicking the “Show” button will display the face cards.
You can download the C# Source Code for the Shuffling and Dealing Cards project.
ArrayShuffling1 Code
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.