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={
      "SA","S2","S3","S4","S5","S6","S7","S8","S9","ST","SJ","SQ","SK", // spade
      "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={
      "SA","S2","S3","S4","S5","S6","S7","S8","S9","ST","SJ","SQ","SK", // spade
      "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();  
    }

  }
}

Further Reading

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;
    }

Thanks for reading. Comments are welcome.

No comments:

Post a Comment