Reputation: 1188
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
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
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
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
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
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