Reputation: 65
How do I shuffle and display cards in Java so that they are only displayed once?
Math.random()
has a chance of being shown twice.
Upvotes: 1
Views: 862
Reputation: 160974
If you want to model a deck of cards, then using a List
as the underlying data structure is one option.
Each element of the List
should be a card -- be it an instance of a Card
class, or maybe something as simple as an Integer
.
The deck will be loaded up with the objects that should compose the deck. Loading the List
can be accomplished by calling List.add
for each element that should be included in the deck.
Picking a random card would entail actually removing a card from the deck. With the List
interface, one would use the List.remove
method. (The actual element being removed could be a random element index which exists within that list.) This way, you wouldn't have to keep track of what cards have already been removed.
If the deck needs to be randomized, then the Collections.shuffle
method can be used. It will take a Collection
(a List
is a subinterface of Collection
) and do an in-place shuffle on the List
.
Taking the above ideas, and using a Card
class that we assume is available, the code might look like this:
// Initialize the deck.
List<Card> deck = new ArrayList<Card>();
// Load up the deck.
deck.add(new Card(Suit.HEART, Rank.ACE));
// and so on...
deck.add(new Card(Suit.SPADE, Rank.KING));
// Shuffle the deck.
Collections.shuffle(deck);
// Take a random card out of the deck.
int sizeOfDeck = deck.size();
Card randomCard = list.remove(new Random().nextInt(size));
// Since we removed the `Card` from the deck, it will not appear again.
Upvotes: 0
Reputation: 114787
If you always shuffle the full deck, there's a good chance to draw a card a second time. If you do not want this, then you must not put the card back on the deck.
A real life game would use a deck, that get's smaller and smaller and a pile of drawn cards, that get's bigger.
It's much easier if you define a "Card" class and use lists that hold those card objects. Then, shuffle the list, get
the top card, add
it to the other list and remove
it from the deck:
public class Card {
String name; // for simplicity, just the card's name
public Card(String name) {
this.name = name;
}
public String getName() {return name;}
}
// ...
List<Card> deck = new ArrayList<Card>();
initDeck(); // adds like 52 new cards to the deck
Collections.shuffle(deck); // shuffle the deck
Card drawn = deck.get(0); // draw the first card
deck.remove(drawn); // remove it from the deck
Upvotes: 0
Reputation: 91092
Since you're probably using an object-oriented programming language, you can do this:
class Deck(object):
private fields:
cardsLeft : list of Card objects
methods:
drawCard() -> randomly takes Card from self.cardsLeft
reset()
class Card(object)
Upvotes: 0
Reputation: 28568
Put 52 cards in an ArrayList
then call
Collections.shuffle(cardList);
and then just deal the first n cards in the list.
Upvotes: 9
Reputation: 54445
In terms of a general approach, you could use two arrays (one for the "deck" and one for the "displayed" cards) and simply remove each card the deck and add it to the displayed cards array after each random selection.
Upvotes: 0
Reputation: 21499
Not sure of any specific api call, but you could easily just track shown cards and if a card is called after already being displayed just do a redraw.
Upvotes: 0