简体   繁体   中英

What is the best data structure to store playing cards held in a player's hand?

I'm beginner in java and I'm currently creating a card game like gin rummy for Android. I want to know what's the best implementation for creating Hand class? What's the best way where to store the card returned by Deck.dealt()?

  1. Array
  2. ArrayList
  3. Vector
  4. HashSet
  5. LinkedList

Also, I would appreciate if anyone could provide a gin rummy open source links.

If you really want to understand the nuances between the collection types, here goes.

List isn't technically appropriate except when the game is Bohnanza (which, ahem, is one of the greatest card games of all time, but I'mma let me finish).

List says, among other things, that one hand containing the Ace and King of Clubs, and another hand containing the King and Ace of Clubs, are fundamentally not the same hand. This is a much stronger dependence on order than simply "well, I want to remember the order that the user wants to see their cards in", which is a property that tons of non-List collections have, like LinkedHashSet and Guava's ImmutableSet .

List also implies that there is some particular significance attached to the card that sits in index N. This is true of no card game I know.

Set isn't generally appropriate for card games -- only the ones that use a single deck of completely unique cards.

To allow duplicates but still have order-independent equality, the type to use is Guava's Multiset . For example HashMultiset or ImmutableMultiset . Note that most multiset implementations represent multiple "equal" cards by storing just the card and a count, so when iterating over them, duplicates of a card you have in your hand must always appear together. If it's important to let the user freely control the order of cards in her hand, you would need LinkedListMultiset .

Now that lesson time is over.... well, let's be honest. Calling myHand.equals(yourHand) , or using an entire hand as a key in a Map is not actually something you're ever going to do... so go ahead and use the ArrayList , you'll be fine. :-)

I think a good idea would be to use an interface (List if element are ordered, or Set if elements are not ordered. You can use the implementation you prefer, for example:

List<Card> deck = new ArrayList<Card>();

or

Set<Card> deck = new HashSet<Card>();

Store them in an ArrayList .

Cards in a hand are in a certain order, not in an unordered pile. This ordering is preserved in a List over a Set .

ArrayList also gives you the opportunity to select a specific card by index, which will be helpful as you implement the game.

Keep in mind that as long as you design your Hand class properly, you can always change this data structure easily at any point in the future. As long as you keep this in mind with any class you design, you can always change it if you realize you need something different.

Well, a HashSet is faster(as far as I know), but if you want to make a card game, then maybe you will wish to sort the cards. That is why I would suggest using a List. If you are a beginner, then maybe the best thing would be to use an ArrayList . It's easy to use and understand. At least this is what I would do. If you want to learn more, I suggest reading about each one's unique properties so that you can decide for yourself. And yes, like greuze said before, you should use an interface for more flexibility.

Firstly, use of Vector is discouraged in the latest versions of Java, so you can probably ignore that one.

Secondly, as you'll know if you're read the Javadoc on those remaining classes, they all have advantages or disadvantages. Some have an order, some can take duplicate values, some cannot and so on. Therefore I think the best approach is to write some pseudo-code for your application which is not based on a specific class (just write things like 'add Card to Hand', 'remove card from Hand'). Once you have some of this pseudo code you will be able to see your requirements more clearly; will you want to keep the cards in the hand in a specific order? will you want to be able to retrieve cards from the hand by a key?

Then, your choice will be clearer.

Keeping the deck in a List makes sense as it does maintain order. I tend to default to using Lists.newArrayList() to create a List. Lists is part of Guava. I strongly recommend using and getting to know Guava since it has many useful offerings.

It would make sense to be able to keep the hand in some data structure that could be sorted easily in order to make it easier to compare hands. OTOH, IIRC, gin rummy hands aren't all that large.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM