Ci sono un paio di cose a cui pensare qui: la struttura di una carta e la struttura della collezione di carte ... e tutto il tempo tenendo presente che questo è Java e dovrebbe essere scritto con la giusta attenzione ai principi orientati agli oggetti.
Una carta è una cosa. Rappresentandolo interamente come un po 'in un BitSet , o peggio .. facendo la tua manipolazione di bit e passando un long
ti distoglie davvero da quei principi orientati agli oggetti. Hai invece a che fare con "Ho il 23 bit che è un gran numero di cuori", che rende alcuni brutti codici. Anche l'iterazione su un bitset o bit impostati in un lungo non è affatto divertente. Quindi, lasciamolo riposare - un po 'non è una carta non è una cosa.
Ci sono approcci basati su questo che non sono sbagliati per Java. Non è irragionevole incollare tutte le carte in enum
:
public enum Card {
ACE_OF_HEARTS,
TWO_OF_HEARTS,
...
KING_OF_SPADES
}
Potresti quindi utilizzare un EnumSet come raccolta. Sì, è supportato da un BitSet quando ci passi dentro, ma è una bella collezione da affrontare. In realtà è una raccolta (un BitSet non lo è) e quindi ottieni gli iteratori e contiene e simili. Un BitSet, stai facendo la tua iterazione a mano chiamando nextSetBit(5)
per scoprire quale sia l'indice del prossimo bit impostato.
Non dirò che l'enum con tutte le carte in esso è sbagliato , ma non è giusto . Se leggi il tutorial sulle enumerazioni di Oracle, puoi persino trovarlo. ..
import java.util.*;
public class Card {
public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX,
SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }
public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }
private final Rank rank;
private final Suit suit;
private Card(Rank rank, Suit suit) {
this.rank = rank;
this.suit = suit;
}
public Rank rank() { return rank; }
public Suit suit() { return suit; }
public String toString() { return rank + " of " + suit; }
private static final List<Card> protoDeck = new ArrayList<Card>();
// Initialize prototype deck
static {
for (Suit suit : Suit.values())
for (Rank rank : Rank.values())
protoDeck.add(new Card(rank, suit));
}
public static ArrayList<Card> newDeck() {
return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
}
}
E hai un mazzo supportato da ArrayList.
Ecco una cosa a cui pensare comunque. Non puoi avere due jack di cuori in mano ... beh, alcuni giochi potresti, ma la maggior parte giochi che non lo fai. Ciò significa che un insieme di carte è un Set . Questo ti dà alcune opzioni su come implementare la mano in modo tale che non significhi matrici di giocoleria.
Vorrei iniziare con un LinkedHashSet
in quanto mantiene l'ordine distribuito, oppure potresti preferire il TreeSet
o ConcurrentSkipListSet
se vuoi che le carte siano nell'ordine ordinato. Nota che questo non è così utile per trattare le carte di un mazzo come vorresti fosse in un List
perché Collections.shuffle prende un elenco come argomenti. Inoltre non devi preoccuparti di tirare le carte fuori dal centro del mazzo quando hai a che fare. Quindi la LinkedList avrebbe funzionato molto per il mazzo stesso quando si trattava di carte (vedi pollFirst se vuoi farlo in quel modo).
Tuttavia, alcuni giochi potrebbero rivelarsi necessario conservarlo in un deque (come ad esempio una LinkedList - in modo da ottenere il sondaggio prima e l'ultima). Altri si desidera mantenere le carte in una struttura ordinata, o altri si potrebbe desiderare qualcos'altro. Tutto dipende da cosa vuoi fare e trovare la raccolta corretta (o meno) per farlo.
Tuttavia, la struttura dati per una carta dovrebbe essere quella della carta presentata da Oracle nel tutorial enum. E poi usi la Collezione che mappa come vuoi tenere le carte.