2012-02-06 47 views
5

在設計應用設計模式的以下類時,最佳方法是什麼?面向卡牌遊戲類的面向對象設計

  • 甲板 - addCard,處理,隨機播放,getTopCard,removeTopCard,removeAllCards
  • - addCard,removeCard,getCard,removeAllCards
  • DiscardPile - addCard,getTopCard ,removeTopCard,removeAllCards
  • MeldPile - addCard,removeAllCards

(該MeldPile持有該表中的所有融合了。)

對於我來說,我覺得getTopCardremoveTopCard都只是一個getCardremoveCard包裝,如它只是獲得一張卡的頂部位置,然後將其傳遞到getCardremoveCard

我應該使用組合?戰略模式?或者只是創建另一個類CardPile並將其用作上述類的基類?真的很感激,如果你能提供一個示例代碼。

+3

最好的方法的邏輯經銷商類是剛開始寫的遊戲規則,讓你的設計自然演變。如果您有特定的問題,例如「我正試圖實施一項規則,如果一名球員在打一張牌時另一名球員必須放棄,我應該在這裏使用什麼樣的模式?」這可能是可以回答的。 – 2012-02-06 13:58:38

+1

+1爲「讓您的設計自然演化」 – radarbob 2012-02-07 20:33:41

+0

請注意將「自然發生」類放入次原子粒子基類中。由於進行不必要的通用和無償處理,類層次結構可能會變得太深。如果你的*自然設計進化*需要一個更一般的基礎來獲得新的功能,你可以在以後總是重構。 – radarbob 2012-02-07 20:40:08

回答

6

我認爲你可以用下面這樣一個單一的甲板類實現你想要的東西,這實際上是一個圍繞Stack的包裝,我不明白爲什麼任何特定的甲板/樁/手不想要大多數,如果不是全部相同方法。

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); 
    } 

} 

唯一真正的問題,我看到的是與deal()方法以及是否這應該是一個甲板的責任?我個人不這麼認爲,這讓我覺得,也許你將有一個播放器類和擴展播放器並實現處理甲板

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

我真的不明白什麼是一個融合樁或聽起來有點MtG屬於一個球員?例如一個MTG風格的遊戲(從我簡短的經驗中玩),玩家將擁有一副牌,一隻手,元素力量打出一點點牌,而這個怪物扮演的角色,我認爲可能是一個'甲板',儘管你可能希望創建一個沒有實現'shuffle()'方法的'Deck'基類,並將其用作'較小的牌疊' – 2012-02-06 14:26:00

+0

我同意你關於處理方法的說法,它不應該作爲交易的一部分是經銷商的行爲。組合牌是一組牌(三合一,四合一和直),屬於在桌上張貼的玩家。我不能決定實現什麼,因爲大多數開源紙牌遊戲在Deck,Hand和Discard Pile中使用不同的類,而另一個只創建一個CardPile並將其用作基類。 – Zack 2012-02-06 14:35:13

+0

我建議首先使用一個CardPile基類,它將封裝添加和從那裏移除卡,你可以繼承它,你可能有一個'Deck'可以混洗和'神奇地創建',一個'MeldPile'擁有它自己可以包含的牌的規則,可以設置允許的最大牌數和放棄規則的「手牌」。更重要的是,我認爲最好是開始一些事情,避免'patternitis'並在需要時重構/優化代碼。 – 2012-02-06 15:04:39