TZPike05
TZPike05

Reputation: 1188

Randomly drawing 5 cards from a deck in Java

I'm trying to learn Java and I wanted to make a very simple class that would randomly select 5 cards from a randomly generated deck of cards. I'm running into something that I feel should be a very simple issue to solve. Also, this is for a lab at the University I attend so if you are able to guide me without giving me blocks of code, that would be preferable.

This is the error I receive, and I understand why I receive it:

The type of the expression must be an array type but it resolved to Deck

Here is my code:

public static void main(String[] args) {
    System.out.println(select(5));
}

public static Card[] select(int k)
{
    Random rand = new Random(52);
    Deck deck = new Deck(52);
    Card[] hand = new Card[5];
    for (int j = 0; j < 5; j += 1)
    {
        int index = rand.nextInt(52-j);
        hand[j] = deck[index];
    }
    return hand;
}

The Deck.java and Card.java classes were provided by my instructor (who is unavailable during lab time).

I also recently realized this code is not going to do for me what I want it to do, however I still need to figure out the error I have above. If you wanted to help with the other issue I have, feel free to answer my explanation below but it's not the reason I am here.

I'm wanting to randomly select 5 cards. Let's say that a randomly selected card is at index 27 of my deck object. I want to then move that card to index 51 and repeat this 4 times. That way the last five cards of my deck object were all randomly selected and it's impossible for them to be selected twice. I am thinking the easiest approach (which I have not attempted yet) would be to create a variable that holds the value of one of my deck indices so I can swap them around. Would any of you agree?

Any help is greatly appreciated!

Upvotes: 0

Views: 10838

Answers (5)

splungebob
splungebob

Reputation: 5415

Just to add to the other suggestions already mentioned,

Card[] hand = new Card[5]; 

should likely read

Card[] hand = new Card[k]; 

and the same goes for your for-loop:

for (int j = 0; j < 5; j += 1) 

should read

for (int j = 0; j < k; j += 1)

Upvotes: 4

Amit Deshpande
Amit Deshpande

Reputation: 19185

You should do

int index = (52 -rand.nextInt(51)+1);

Also you need a Deck[] of 52

  Deck[] deck = new Deck[52];
  for(i to 52)
  //Initalize deck[i] here 
  end.
  Now you can access like deck[index]

I think using enum you can implement Card Game in a better way.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

// This is just sample example  and it is just to show an approach. I had not enough time    to make code perfect but it works fine.
public enum Deck
{
DECK;
enum Rank
{
    DEUCE(2), THREE(3), FOUR(4), FIVE(5), SIX(6),
    SEVEN(7), EIGHT(8), NINE(9), TEN(10), JACK(10), QUEEN(10), KING(10), ACE(11);

    Rank(int rank)
    {
        this.rank = rank;
    }

    private final int rank;

}

enum Type
{
    SPADES,
    HEARTS,
    DIAMONDS,
    CLUBS;
}

class Card
{
    private final Rank rank;
    private final Type type;

    Card(Rank rank, Type type)
    {
        this.rank = rank;
        this.type = type;
    }

    @Override
    public String toString()
    {
        return type.name() + rank.name();
    }

}

static List<Deck.Card> cards = new ArrayList<Deck.Card>();
static
{
    for (Rank rank : Deck.Rank.values())
    {
        for (Type type : Deck.Type.values())
        {
            cards.add(DECK.new Card(rank, type));
        }
    }

}

List<Deck.Card> shuffle()
{
    Collections.shuffle(cards);//Once it is shuffled you can use it to draw first five cards same way we play
    System.out.println(cards);
    System.out.println(cards.size());
    return Collections.unmodifiableList(cards);
}

public static void main(String[] args)
{
    DECK.shuffle();
}
}

Upvotes: 2

Marko Topolnik
Marko Topolnik

Reputation: 200168

public static Card[] select(int k)
{
  Random rand = new Random(52); // mistake 1
  Deck deck = new Deck(52);     // mistake 2
  Card[] hand = new Card[5];
  for (int j = 0; j < 5; j += 1)
  {
    int index = rand.nextInt(52-j);
    hand[j] = deck[index];     // mistake 2
  }
  return hand;
}

Mistake 1: do not initialize Random with a constant number. This will make your pseudorandom sequence always exactly the same.

Mistake 2: either your declaration Deck deck is wrong, or the way you try to access deck[index], since deck is not declared as an array. Since Deck is a class that represents a collection of cards, the more logical culprit is the latter line. Change to a call of an appropriate Deck method.

Without knowing the implementation of Deck it is impossible to know the correct code. If Deck is by its nature a random deck of cards, then you should just take the top 5. If it is completely sorted (which would not be a realistic deck, I should add), then you need to pick random cards off it. The Deck class should at least have a remove method, that will immediately solve your problem with duplicates.

Upvotes: 2

Subhrajyoti Majumder
Subhrajyoti Majumder

Reputation: 41210

Do shuffle on cards and pick, it is better than using Random selection because there would be chance of duplicate but if you use shuffle then it would not be. You can use Collections#shuffle.

Upvotes: 1

Rohit Jain
Rohit Jain

Reputation: 213281

You have your deck as reference of class Deck pointing to an instance: -

Deck deck = new Deck(52);

So, you can't access it on index like array: -

deck[index];  // Cannot do this on a reference pointing to object of `Deck`

I think you probably need to give some method in your class like get(index) and access it like: - deck.get(index)

Or may be you wanted to declare your deck as: -

Deck[] deck = new Deck[52];

then that (deck[index])would work.

Upvotes: 4

Related Questions