1

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.

Jeff Atwood
  • 63,320
  • 48
  • 150
  • 153
gheystyle
  • 65
  • 3
  • 9

6 Answers6

9

Put 52 cards in an ArrayList

then call

Collections.shuffle(cardList);

and then just deal the first n cards in the list.

MeBigFatGuy
  • 28,272
  • 7
  • 61
  • 66
0

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.

Steve
  • 21,163
  • 21
  • 69
  • 92
0

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.

John Parker
  • 54,048
  • 11
  • 129
  • 129
0

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
Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
0

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)
ninjagecko
  • 88,546
  • 24
  • 137
  • 145
0

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.
coobird
  • 159,216
  • 35
  • 211
  • 226