Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java random values and duplicates

I have an array (cards) of 52 cards (13x4), and another array (cardsOut) of 25 cards (5x5). I want to copy elements from the 52 cards into the 25 card array by random.

Also, I dont want any duplicates in the 5x5 array. So here's what I have:

        double row=Math.random() *13;
        double column=Math.random() *4;

        boolean[][] duplicates=new boolean[13][4];

        pokerGame[][] cardsOut = new pokerGame[5][5];
        for (int i=0;i<5;i++)
            for (int j=0;j<5;j++){
                if(duplicates[(int)row][(int)column]==false){
                    cardsOut[i][j]=cards[(int)row][(int)column];
                    duplicates[(int)row][(int)column]=true;
                }
            }

2 problems in this code. First, the random values for row and column are only generated once, so the same value is copied into the 5x5 array every time. Since the same values are being copied every time, I'm not sure if my duplicate checker is very effective, or if it works at all.

How do I fix this?

like image 450
Snowman Avatar asked Dec 22 '10 01:12

Snowman


People also ask

How will you generate a random number which does not get repeated?

We do this by shuffling the numbers as we generate the random numbers, instead of doing it beforehand. This is done by keeping track of how many numbers we've generated so far, and for each new number, we pick a random one from the unused set, swap it into the used set and then return it.

Does random nextInt repeat?

Yes it will. Since the generator has a finite amount of state, the generated sequence has a finite period.

How do you generate a double random value in Java?

In order to generate Random double type numbers in Java, we use the nextDouble() method of the java. util. Random class. This returns the next random double value between 0.0 (inclusive) and 1.0 (exclusive) from the random generator sequence.


2 Answers

I'd recommend shuffling the deck in place first, then selecting the first 25 cards to place in your 5x5 array. Trying to mix these two steps is unnecessary complication.

If you need to optimize for performance (you probably don't) then it is worth noting that you can use the Fisher-Yates shuffle and stop the algorithm after the first 25 random cards have been selected without shuffling the remaining cards.

like image 57
Mark Byers Avatar answered Oct 25 '22 10:10

Mark Byers


I think your approach makes it more difficult than it should be. Try using a class named card, and two collections - one named CardsRemaining and another named CardsUsed.

Initially, CardsRemaining contains all 52 card objects, and CardsUsed is empty. As cards are added to CardsUsed, they are removed from CardsRemaining, naturally preventing duplicates from occuring.

Your program might end up looking something like this (sorry it's in c#):

  class Program
    {
        static void Main(string[] args)
        {
            List<Card> CardsRemaining=new List<Card>();
            for (int i = 0; i < 12; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    Card c = new Card(i, j);
                    CardsRemaining.Add(c);
                }
            }
            List<Card> CardsUsed = new List<Card>();
            for(int i=0;i<25;i++)
            {
                int cardIndex = getRandomNumber(CardsRemaining.Count);
                Card c = CardsRemaining[cardIndex];
                CardsRemaining.Remove(c);
                CardsUsed.Add(c);
            }
        }
    }

    class Card
    {
        public int Number;
        public int Color;
        public Card(int number, int color)
        {
            this.Number = number;
            this.Color = color;
        }
    }
like image 31
Greg Sansom Avatar answered Oct 25 '22 10:10

Greg Sansom