Random in java

T

Thomas Korsgaard

Hello,

I have a question conserning generation of random numbers in java. I'm
developing a little cardgame. In order to do so i have created a class
Deck which contains of 52 Card objects (which I alsp have created).
These "Cards" are stored in an Card array. I want to be able to
"shuffle" the deck, and in order to do so I have created shuffle(),
whitch takes a card from the deck an puts it in the back:

Random r1 = new Random();
void shuffle(){
for(int i=0;i<4000;i++){
int pos = r1.nextInt(52);
Card temp = d1[pos];
this.getCard(pos);
this.putCard(temp);
}
}

This works fine! No problems. The problem comes when I start testing
this on loads many decks. If I run a test like:

Deck lots[] = new Deck[20];
for(int i=0;i<lots.length;i++) {
// Init deck
lots = new Deck();
// Shuffel the deck
lots.shuffle();
// What are the ten top cards
for(int j=0;j<10;j++){
lots.showCard(j).printCard();
}
System.out.println("");
}

And the output is as follows:

7D 5H 8D 9H KD KC QS 7S 3D 2D
8H JH QC 2S 8C 2D 5D 5C KC 2H
8H JH QC 2S 8C 2D 5D 5C KC 2H
7H KS 2D 6S 8S 2H 6H 2C QH 4D
7H KS 2D 6S 8S 2H 6H 2C QH 4D
6H 8C 4S 2C JS AC 3S 10H 3C KH
6H 8C 4S 2C JS AC 3S 10H 3C KH
6H 8C 4S 2C JS AC 3S 10H 3C KH
6H 8C 4S 2C JS AC 3S 10H 3C KH
QD 10S QS 3H 9S 2H 8D QH 7S 3C
QD 10S QS 3H 9S 2H 8D QH 7S 3C
QD 10S QS 3H 9S 2H 8D QH 7S 3C
QD 10S QS 3H 9S 2H 8D QH 7S 3C
4S AS 5D QD 2D 7H 9D 3S 5C 10C
4S AS 5D QD 2D 7H 9D 3S 5C 10C
JS 8C 7S KD 6D 2H 8S QD 9C 3H
8H 6D QD 5H QC 6C 10C 10H 3S AH
9S 3H 3C KS 6D QS 8S JD 3D 6H
9S 3H 3C KS 6D QS 8S JD 3D 6H
9S 3H 3C KS 6D QS 8S JD 3D 6H

As you can see it shuffels some deck the same way! And I think this is
due to my random generator ...

Can anybody help me?

Cheers,
/Thomas
 
O

Oliver Wong

Thomas Korsgaard said:
Hello,

I have a question conserning generation of random numbers in java. I'm
developing a little cardgame. In order to do so i have created a class
Deck which contains of 52 Card objects (which I alsp have created). These
"Cards" are stored in an Card array. I want to be able to "shuffle" the
deck, and in order to do so I have created shuffle(), whitch takes a card
from the deck an puts it in the back:
[snip]
As you can see it shuffels some deck the same way! And I think this is due
to my random generator ...

Can anybody help me?

How many ways are there to order 52 cards? 52! ~= 8 * 10^67 ~= 225 bits of
entropy

From the javadoc for java.util.Random: "The class uses a 48-bit seed"

In other words, if you really care about the randomness of the deck (e.g.
for security/encryption reasons), Java's Random class doesn't provide enough
randomness.

But if you don't really care that much (e.g. this is just for a simple
game), then you might want to try solving your problem by creating only 1
instance of the Random object, and sharing it across all the shuffles,
instead of creating a new Random object for each shuffle. You might be
creating Random objects so quickly that they receive the same seed (which is
based on the current time).

- Oliver
 
A

Andrew Thompson

Thomas said:
I have a question conserning generation of random numbers in java. ...
As you can see it shuffels some deck the same way! And I think this is
due to my random generator ...

The random number generator in Java provides a sequence of
numbers based upon a 'seed' that is 'sown' when it is instantiated.

By recreating the Random object inside the loop, you end up
getting the same seed for the sequence, since it is taken
from the currentTimeMillis AFAIR.

Move the declaration of your 'random' object outside the
loop and it should come good. There are a nuumber of ways
you can declare (and instantiate) the random number object
outside the method (which is called many times), but still
use it inside the method. E.G.
- declare the Random object as a class variable and instantiate
it in the constructor.
- declare the Random object just before the loop, and
pass it to the method as an argument.

HTH
 
T

Thomas Korsgaard

Oliver, Andrew -

Thanks for the help. Moving the creation of the Random object out of the
Deck class and into the main class helped, so every Deck uses the same
Random object instead of having their own.

I found a usefull page, if others are interested.
http://www.cs.geneseo.edu/~baldwin/reference/random.html

Thanks
/Thomas


<OT>
------
Oh .. by the way, Mr. Thomas "Usenet-Police" Weidenfeller, if you don't
like the way I post messages and code, all you got to do is ignore it.
Simple.


Thomas said:
What is that supposed to do? What is 'this'? For the n-th time today:

http://www.physci.org/codes/sscce.jsp

</OT>
 
T

Thomas Hawtin

Thomas said:
Random r1 = new Random();

As others have said, call this in rapid succession and it'll start from
the same seed. Particularly so on operating systems with bad real time
clock handling (mentioning no Windows in particular).
void shuffle(){
for(int i=0;i<4000;i++){
int pos = r1.nextInt(52);
Card temp = d1[pos];
this.getCard(pos);

I bet getCard actually means removeCard.
this.putCard(temp);

addCard would be more conventional.

This is a really inefficient way to shuffle. Fortunately there is a nice
java.util.Collections.shuffle method so you don't need to get into the
details (although they are in Java Puzzlers, if you are interested
http://www.amazon.co.uk/exec/obidos/ASIN/032133678X/).

Tom Hawtin
 
R

Roedy Green

Card temp = d1[pos];
this.getCard(pos);
this.putCard(temp);

What is that supposed to do? What is 'this'? For the n-th time today:

That looks like an attempt to swap two elements.

The author is confused between the difference between a slot number
and the element at that slot.

We don't have the entire code, but he might also be confused between a
class containing an ArrayList and an ArrayList.


A getCard method would have a signature like this:

x getCard( int position )

where x is int, Card or whatever you use to represent your card.

A putCard method would have a signature like this:

void putCard( int position, x card );
 
R

Roedy Green

Oh .. by the way, Mr. Thomas "Usenet-Police" Weidenfeller, if you don't
like the way I post messages and code, all you got to do is ignore it.
Simple.

You asked for help. You ignored Mr. Weidenfeller's question. I don't
see how that rates a "Usenet-Police" crack.

The help you get on Usenet is being asked questions and given things
to try.

If you went to dinner at somebody's house and refused to eat the meal
and made no explanation of why, your hosts might feel offended. The
same happens on newsgroups when people prepare posts for you designed
to help solve your problem.

Your problem is more difficult that average because you did not give a
clear explanation of what you were trying to do. We are all making
guesses. All we have is the vague notion it has something to do with
simulating shuffled cards. Next we don't have the complete code.
Without that we can only guess at what the code you did provide does.
 
T

Thomas Weidenfeller

Roedy said:
You asked for help. You ignored Mr. Weidenfeller's question. I don't
see how that rates a "Usenet-Police" crack.

Roedy, don't waste your time on such idiots. Plonk him and be done.

/Thomas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top