Saturday, March 19, 2011

How to shuffle playing card in Java ?

If you are writing playing card games such as bridge or black jack, the first thing you should know is how to implement a card shuffling algorithm.

Representation :
A deck of playing cards can be represented by an array of 52 integers or by an array of Strings.

Integer array are more efficient whereas String array are simple and readable. Since this site is focused on simplicity and readability, String array will be used.

// code segment for playing card representations
String[] deck={
"HA","H2","H3","H4","H5","H6","H7","H8","H9","HT","HJ","HQ","HK", // heart
"CA","C2","C3","C4","C5","C6","C7","C8","C9","CT","CJ","CQ","CK", // club
"DA","D2","D3","D4","D5","D6","D7","D8","D9","DT","DJ","DQ","DK"  // diamond
};

Shuffling

Shuffling a deck of card is simple, just pick two cards at random, exchange their positions in the deck, and repeat this process for hundreds of time.

// Shuffle
java.util.Random random=new java.util.Random();
for (int i=0;i<100;i++)
{
// pick two card at random position
int card1 = Math.abs(random.nextInt()) % 52;
int card2 = Math.abs(random.nextInt()) % 52;

// exchange their position in deck
String tmp = deck[card1];
deck[card1] = deck[card2];
deck[card2] = tmp;
}

A full example is listed below.

/******************************************************************************
* File : Shuffler.java
* Author : http://java.macteki.com/
* Description :
*   Shuffle a deck of playing cards.
* Tested with : JDK 1.6
******************************************************************************/

public class Shuffler
{
public static void main(String[] args) throws Exception
{
String[] deck={
"HA","H2","H3","H4","H5","H6","H7","H8","H9","HT","HJ","HQ","HK", // heart
"CA","C2","C3","C4","C5","C6","C7","C8","C9","CT","CJ","CQ","CK", // club
"DA","D2","D3","D4","D5","D6","D7","D8","D9","DT","DJ","DQ","DK"  // diamond
};

// display unshuffled deck
for (int i=0;i<52;i++)
{
System.out.print(deck[i]+" ");
// line break after displaying every 13 cards
if ((i+1)%13==0) System.out.println();
}

// Shuffle
java.util.Random random=new java.util.Random();
for (int i=0;i<100;i++)
{
// pick two card at random position
int card1 = Math.abs(random.nextInt()) % 52;
int card2 = Math.abs(random.nextInt()) % 52;

// exchange their position in deck
String tmp = deck[card1];
deck[card1] = deck[card2];
deck[card2] = tmp;
}

// display shuffled deck
System.out.println("\nShuffled deck :");
for (int i=0;i<52;i++)
{
System.out.print(deck[i]+" ");
// line break after displaying every 13 cards
if ((i+1)%13==0) System.out.println();
}

}
}

After the implementation of the above method, a better shuffling algorithm was found in the web. It is known as the "Fisher-Yates" shuffle.
//Fisher–Yates shuffle
for (int i=0;i<deck.length;i++)
{
int randomIndex=random.nextInt(deck.length);
String tmp=deck[i];
deck[i] = deck[randomIndex];
deck[randomIndex] = tmp;
}