I have an Array List of cards containing 52 cards. I want to shuffle the deck.
This is what I have done.
Here is my code:
String[] Number = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
String[] Suits = {"Club","Diamonds","Hearts","Spades"};
ArrayList<Card> deck = new ArrayList<Card>();
// create a deck
for(int i=0;i<13;i++){
for(int j=0;j<4;j++){
Card card = new Card(Suits[j],Number[i]);
deck.add(card);
}
}
// shuffle of deck
ArrayList<Card> new_deck = new ArrayList<Card>();
while(deck.size()!=0){
Random rand = new Random();
int n = rand.nextInt(deck.size());
new_deck.add(deck.get(n));
deck.remove(n);
}
// Display
for(int i=0;i<52;i++){
System.out.println(new_deck.get(i).getSuit()+" : "+new_deck.get(i).getValue());
}
Finally, I get the shuffled deck from new ArrayList.
Is its randomness good enough or not?
What should I do to increase randomness?
Does it's randomness is enough or not ?
Define good enough (!!)
Your current approach is going to give a good shuffle, with no obvious biases ... except for biases that may be introduced by the random number generator.
And in this case, there is real cause for concern. Random is specified to be a linear congruential generator, and LC generations have distinct patterns in the numbers that they generate. (In statistical terms, they show strong auto-correlation.) This is quite clear if you graph the n'th random number against n.
To improve randomness, you should use a better random number generator. The SecureRandom generator should be good enough: javadoc.
The same concern about the randomness applies if you use Collections.shuffle method. For a good (or consistent) shuffle you should use the method overload where you supply a Random implementation ... and choose a good one.
I suggest you can simply use Collections.shuffle() as shown below rather than reinventing the shuffling logic which is already provided by Collections API:
Collections.shuffle(deck);//Pass your ArrayList<Card> object i.e., deck
So, by reusing this existing Collections API clears all your doubts on the randomness of your deck object.
You should define your notion of "randomness" in a precise way. "Increasing randomness" is a rather vague term.
I will assume by "random", what you want is a uniform distribution of permutation on your deck. Which is to say, you want your deck to be reordered in such a way that the chance that the next card is a particular card is equal.
There are two different factors at play here:
Random isAs far as how you shuffle goes, it is uniform. It can be proven by conditional probability that any card being in any position is exactly 1/52.
util.Random isFirst, to be clear, util.Random is not actually random. It is a pseudorandom number generator(PRNG). That means what they do is not to produce truly random numbers. Instead they try to, and depending on application requirements, it will be enough.
util.Random is a linear congruential generator, and as far as PRNGs go, its pretty weak. If you don't care about really randomizing your deck, it will work fine. However if you need something more robust, here is a starting point.