Tuesday, March 12, 2013

Implementation of a Card Shuffling Algorithm in Java


About 15 months ago, I had an interview in a company around  Da Qiao Tou station. The supervisor asked me about how to efficiently shuffle cards by C#, and I didn't quickly figured out a good answer. Finally, he said that the most efficient card Shuffling algorithm is to do thousands or a millions times of swap of two randomly chosen cards. I didn't think clearly and assumed that his view is correct. Now I realized that the algorithm he said is not efficient enough, much less the most efficient algorithm.

The following is a Java implementation of a card shuffling algorithm which took just a few thousands of simple addition by 1 or subtraction by one. The generated deck of card is completely random provided that random numbers generated with java.util.Random and its methods are random. You can copy the codes and configure them on your own.



Card.java

package com.cardshuffler;

public class Card {
 public enum Suit{
  Club, Diamond, Heart, Spade, 
 }
 
 public final Suit suit;
 public final int number; //J is represented by 11, and Q by 12, K by 13
 public Card(Suit suit, int number) {
  this.suit = suit;
  this.number = number;
 }
 
 @Override
 public String toString(){
  return suit + "-" + number;
 }
}


CardShuffler.java

package com.cardshuffler;

import java.util.*;
import com.cardshuffler.Card.Suit;

public class CardShuffler {

 private Random random;
 private ArrayList cards;

 public CardShuffler() {
  cards = new ArrayList();
  random = new Random();
 }

 public void shuffle() {
  final int cardNum = 52;
  boolean[] selected = new boolean[cardNum];
  for (int i = cardNum; i >= 1; i--) {
   int count = -1;
   int randomNumber = random.nextInt(i) + 1;
   for (int j = 0; j < randomNumber ; j++){
    count++;
    while (selected[count])
     count++;
   }
   selected[count] = true;
   cards.add(getCardByNumber(count));
  }
 }

 /**
  * the input number should be between 0 to 51
  * @param number
  * @return
  */
 private Card getCardByNumber(int number) {
  Suit suit = null;
  int a = number / 13;
  switch (a) {
  case 0:
   suit = Suit.Club;
   break;
  case 1:
   suit = Suit.Diamond;
   break;
  case 2:
   suit = Suit.Heart;
   break;
  case 3:
   suit = Suit.Spade;
   break;
  }
  
  return new Card(suit, number%13 + 1);
 }

 public ArrayList getCards() {
  return cards;
 }

 public static void main(String[] args) {
  CardShuffler shuffler = new CardShuffler();
  shuffler.shuffle();
  List shuffledCards = shuffler.getCards();
  
  System.out.println("The resulting shuffled cards are:");
  for (Card card : shuffledCards)
   System.out.println(card);
  
 }
}

No comments:

Post a Comment