[java] My Kingdom for a Random algorithm

Started by
6 comments, last by cyrax256 22 years ago
Hello. I´m doing now a little UNO game (you know, the card game in which you have annoying cards as the Draw Two, Reverse, etc.) just for kicks, and to practice the language. The logic is still under work, but right now I have a rather functional game. But there is a thing that I want to work well. You see, the Random class in Java is not good: the Shuffle function for the deck works well for the first 30 or 40 cards, but the rest of the deck is almost untouched. This gives as a result the first 30 cards shuffled and a big zone of ordered yellow, green and blue cards. I´d like to know if you have a good site about this random issue, or a good book, or even a good code! ;-), in short, if you have any useful information about this, I´d be very grateful. Thank you El Cyrax256
Ciro Durán :: My site :: gamedev.net :: AGS Forums
Advertisement
Hmm, I''ve never heard of anything like this. And I have seen several done in java. I am actually getting ready to make a black jack trainer. Do you have some code from your shuffle function that we can see? I have a feeling the problem might lay in there first.

Hey when you have a link post it so we can take it for a test drive.

Good luck.

-Just when you think things are starting to look up, life grabs you by the jaws makes you open up wide and sh*ts down your throat.
Here it is a stripped part of the class Deck. It is not complete, but shows you more or less the random function

/**
Class: UNODeck
Description: This class sets the UNO cards
*/
import java.util.*;

class UNODeck {

static int luck = 1;
private Vector cards;

private void initCards(Vector cards) {

for (int i = Card.RED; i != 4; i += 1) {

for (int k = 0; k != 2; k++) {
for (int j = 0; j != 10; j++) {
cards.add(new Card(i, j));
}
}

for (int j = 0; j != 2; j++) {
cards.add(new Card(i, Card.DRAW_TWO));
cards.add(new Card(i, Card.REVERSE));
cards.add(new Card(i, Card.SKIP));
}
}

for (int i = 0; i != 4; i += 1) {
cards.add(Card.NULL, new Card(Card.NULL, Card.WILD));
}

for (int i = 0; i != 4; i += 1) {
cards.add(i, new Card(Card.NULL, Card.WILD_FOUR));
}

shuffleDeck(); //This deals the deck
}

public void shuffleDeck() {
Vector randomDeck = new Vector (cards.size(), 0);

for (int i = 0; i != cards.capacity(); i += 1) {
randomDeck.add(this.getCard(getRandomCard()));
}

cards = randomDeck;
}

private int getRandomCard() {

Random rand = new Random();

int lucky = rand.nextInt(cards.size());

return lucky;
}
}

I´ll probably upload the complete code in my site, check it out next week: http://go.to/elciro
Ciro Durán :: My site :: gamedev.net :: AGS Forums
Ah haaa...

private int getRandomCard() {

Random rand = new Random();

int lucky = rand.nextInt(cards.size());

return lucky;
}


That''s your problem. Make random a class level property and not a function level. Since the timers under java are hit and miss ( 54ms resolution uner Win9x ) as the deck gets smaller the more likely that each time you call new Random you will end up with the same seed! This will lead to large blocks of the same number being called.

Actually just put Random rand = ... in the shuffle desk and replace getRandom with rand.nextInt(cards.size());

Good luck. You just had an overengenerring oversight. We all get nearsighted after working on the same code for a while.

Also... why

public void shuffleDeck() {
Vector randomDeck = new Vector (cards.size(), 0);

for (int i = 0; i != cards.capacity(); i += 1) {
randomDeck.add(this.getCard(getRandomCard()));
}

cards = randomDeck;
}


When you could just do

public void shuffleDeck() {
Random rand = new Random();
Vector randomDeck = new Vector (cards.size(), 0);

while(!cards.isEmpty()){
randomDeck.add(this.getCard(rand.nextInt(cards.size())));
}

cards = randomDeck;
}


Since cards.capacity will fail if you had just created cards = new Vector and added cards since it expands by powers of 2.
quote:Original post by snowmoon
When you could just do

while(!cards.isEmpty()){
randomDeck.add(this.getCard(rand.nextInt(cards.size())));
}


** Mental note to myself: read the WHOLE Vector page of the API ** :-)

Thanks for the help, I´ll correct that part and I´ll note you any changes. :-)

El Cyrax256
Ciro Durán :: My site :: gamedev.net :: AGS Forums
Why not use Math.random() instead of manually creating a Random object? It will abstract the programmer from the seed theory and creation of Random object and preventing them from making such errors that easily can be made.

quote:Original post by zappsweden
Why not use Math.random() instead of manually creating a Random object? It will abstract the programmer from the seed theory and creation of Random object and preventing them from making such errors that easily can be made.



Because Math.random() returns a double. If you want an int, it''s a lot faster to use nextInt on a Random object, and the results are more accurate random.

However, I''ve got a better solution to the original problem.


  public void shuffleDeck(){    Collections.shuffle(deck);}  


There''s a lot of stuff in the java API. Sometimes there''s even what you need.

This topic is closed to new replies.

Advertisement