2012-02-06 17 views
5

Quale sarebbe l'approccio migliore quando si progettano le seguenti classi applicando modelli di progettazione?OOP Design per le classi di giochi di carte

  • Deck-AggiungeCarta, affare, shuffle, getTopCard, removeTopCard, removeAllCards
  • mano-AggiungeCarta, RimuoviCarta, getCard, removeAllCards
  • DiscardPile-AggiungeCarta, getTopCard , removeTopCard, removeAllCards
  • MeldPile-AggiungeCarta, removeAllCards

(Il MeldPile detiene tutte le combinazioni nella tabella.)

Per quanto mi riguarda, penso che il getTopCard e removeTopCard sono solo un involucro di getCard e removeCard, come basta prendere la prima posizione di una carta e poi passarla a getCard o removeCard.

Devo usare la composizione? modello di strategia? o semplicemente creare un'altra classe chiamata CardPile e usarla come classe base della classe precedente? Apprezzo davvero se tu potessi fornire un codice di esempio su questo.

+3

L'approccio migliore è quello di iniziare solo a scrivere il regole del gioco e lascia che il tuo design si evolva in modo naturale. Se hai una domanda specifica, ad es. 'Sto cercando di implementare una regola in cui se un giocatore gioca una carta l'altra gioca deve scartare, quale schema dovrei usare qui?' quello potrebbe essere responsabile –

+1

+1 per "fa evolvere il tuo progetto in modo naturale" – radarbob

+0

Fai attenzione a come devolvere le classi "presenti in natura" in classi di particelle sub-atomiche. Le gerarchie di classi possono andare troppo in profondità con l'elaborazione inutilmente generica e gratuita in corso. Puoi sempre refactoring in un secondo momento se la tua * evoluzione naturale del design * richiede una base più generale da cui derivare nuove funzionalità. – radarbob

risposta

6

Penso che tu possa ottenere quello che vuoi con una classe single deck come di seguito che è essenzialmente un wrapper attorno a Stack, non vedo perché nessun mazzo/pila/mano particolare non vorrebbe più se non tutto lo stesso metodi.

class Deck { 
    private Stack<Card> cards = new Stack<Card>(); 

    public Deck() { } 

    public Deck(int numberOfCards) { 
     for (int i=0; i<numberOfCards; i++) { 
      cards.push(CardFactory.createCard(i)); 
     } 
    } 

    private void shuffle() { 
     Collections.shuffle(this.cards); 
    } 

    public void sort() { 
     Collections.sort(this.cards); 
    } 

    public void removeAllCards() { 
     this.cards.removeAllElements(); 
    } 

    public void removeCard(Card c) { 
     int i = this.cards.search(c); 
     this.cards.remove(i);    
    } 

    public Card getCard(Card c) { 
     int i = this.cards.search(c); 
     return this.cards.get(i); 
    } 

    public Card getTopCard() { 
     return this.cards.pop(); 
    } 

    public Card getNthCard(int i) { 
     return this.cards.get(i); 
    } 

    public Card addCard(Card c) { 
     this.cards.push(c); 
    } 

} 

L'unico vero problema che vedo è il metodo deal() e se questo dovrebbe essere la responsabilità di un ponte? Personalmente io non la penso così, questo mi porta a pensare che forse si potrebbe avere una classe Player e una classe del rivenditore che si estende Player e implementa la logica di affrontare un mazzo

class Player() { 
    protected String name; 
    protected Deck hand = new Deck(); 

    public void addCard(Card c) { 
     this.hand.addCard(c); 
    } 

    // ..... 
} 

class Dealer() extends Player { 
    private Deck deck; 

    public Dealer(int deckSize) { 
     this.deck = new Deck(deckSize); 
    } 

    public void deal(Player[] players, int numberOfCards) { 
     for (player in players) { 
      for (int i=0; i<numberOfCards; i++) { 
       player.addCard(this.deck.getTopCard()); 
      } 
     } 
    } 

    // ..... 
} 
+0

Non ho davvero capito cosa fosse una pila di fusione o suoni un po 'MtG appartiene a un giocatore? Per esempio un gioco in stile MtG (dalla mia breve esperienza di gioco) il giocatore avrebbe un mazzo, una mano, il potere giocato dalle carte dell'elemento bit e la parte del mostro giocata tutto ciò che penso potrebbe essere un "Deck" anche se potresti voler creare una classe base di 'Deck' che non implementa metodi come 'shuffle()' e usarlo come 'stack di carte minori' –

+0

Sono d'accordo con te per quanto riguarda il metodo deal, non dovrebbe essere parte di un mazzo come trattare è il comportamento del rivenditore. Una pila di fusione è un insieme di carte (Tris, Four of of a Kind e Straight) che appartengono a un giocatore che ha postato sul tavolo.Non riesco a decidere cosa implementare perché la maggior parte dei giochi di carte open source utilizza classi diverse per Deck, Hand e Discard Pile e mentre l'altra ha appena creato un CardPile e lo usa come classe base. – Zack

+0

Ti suggerisco di iniziare usando una singola classe base CardPile che incapsulerebbe l'aggiunta e la rimozione di carte da lì puoi ereditarla dove potresti avere un 'Deck' che può essere mischiato e 'magicamente creato', un' MeldPile' che ha le proprie regole per le carte che può contenere, una "mano" che può impostare un numero massimo di carte consentite e regole da scartare. Ancora più importante, penso che sarebbe meglio solo iniziare qualcosa, evitare "patternitis" e rifattorizzare/ottimizzare il codice se e quando richiesto. –