2017-03-02 82 views
0
public static ArrayList<Hand> getPossibleHands(Hand h) { 
    ArrayList<Hand> allPossible = new ArrayList<Hand>(); 
    addNext(allPossible, h); 
    return allPossible; 
} 

public static void addNext(ArrayList<Hand> poss, Hand h) { 
    if (h.cards.size() == 5) 
     poss.add(h); 
    else 
     for (int i = 0; i < 52; i++) { 
      Card c = Card.makeCard(i); 
      if (!h.contains(c)) 
       h.add(c); 
      addNext(poss,h); 
     } 
} 

上面的代碼基本上是一個不完整的撲克牌(0-4卡的任何地方),並返回所有可能的完整板卡(5張牌)。我覺得應該遵循的邏輯如下:通過添加有效(不在板上)卡的每個組合的遞歸,直到板的尺寸等於5,在這種情況下,它將板添加到列表中,並且跳過功能的其餘部分。如何調試我的撲克遊戲遞歸邏輯?

但是,在函數的開始處使用print語句時,我會看到手的大小大於5或正在創建。由於該函數的第一部分應該抓住所有5,並在那裏結束它,所以我沒有看到代碼是如何在函數的其餘部分執行的。

+0

是否出牌的順序有關係嗎?也就是說,如果兩隻手在牌的順序上僅有區別,那麼它們是否被認爲是不同的? –

+0

@斯科特獵人不,訂單並不重要 –

回答

0

最初,h(假定)是空的。所以addNext將循環所有可能的牌,並且因爲他們都不在手中,所以無論手中有多少牌,都將每張牌添加到牌上。

-1

在循環中運行52次迭代。在每次迭代中,你(有條件地)在牌上添加一張牌,然後遞歸地調用你的函數。但在遞歸調用返回之後,您將進入下一次迭代並再次添加一張牌。

所以'5卡限制'在這裏不限制任何東西。

0

它在我看來像你的for循環最終將整個甲板添加到手中。

1

你的班級應該會空着手接受堆棧溢出。 您發送新卡(0)到手上。這是添加的。 然後你再次調用add next - 並且'for'再次從0開始。檢查增加1.然後從0開始 - 它在那裏,不添加任何東西並重新開始。它從0開始。什麼都不做。從0開始。Ad infinum - > StackOverFlow。

每次完成5張卡片和回溯時,您還需要重置爲手的前一狀態。

如果你想要一個遞歸解決方案,您可以嘗試:

private static ArrayList<Hand> getPossibleHands(Hand h) { 
     ArrayList<Integer> except; 
     if (h.cards == null) except = new ArrayList<>(); 
     else 
      except = h.cards.stream().map(c -> (c.getCard())).collect(Collectors.toCollection(ArrayList::new)); 
     ArrayList<Hand> allPossible = new ArrayList<>(); 
     addNext(allPossible, h, except); 
     return allPossible; 
    } 

    private static void addNext(ArrayList<Hand> poss, Hand h, ArrayList<Integer> except) { 
     //assuming hands 0-4 - we don't need to check on entry, only when we add 
     Hand localHand = h.copy(); 
     for (int i = 0; i < 52; i++) { 
      if (except.contains(i)) continue; 
      Card c = Card.makeCard(i); 
      if (!localHand.contains(c)) { 
       addNext(poss, localHand.copy(), copyExcept(except, i)); 
       localHand.add(c); 
       if (localHand.cards.size() == 5) { 
        poss.add(localHand); 
        break; 
       } 

      } 
     } 

    } 

    private static ArrayList<Integer> copyExcept(ArrayList<Integer> except, int i) { 
     ArrayList<Integer> clonedExcept = new ArrayList<>(except); 
     clonedExcept.add(i); 
     return clonedExcept; 
    } 


import java.util.ArrayList; 

public class Hand { 
    ArrayList<Card> cards = new ArrayList<>(); 

    public boolean contains(Card c) { 
     for (Card card : cards) { 
      if (card.getCard() == c.getCard()) 
       return true; 
     } 
     return false; 
    } 

    public void add(Card c) { 
     cards.add(c); 
    } 

    Hand copy() { 
     Hand temp = new Hand(); 
     for (Card c : cards) { 
      temp.add(new Card(c.getCard())); 
     } 
     return temp; 
    } 
} 


class Card { 
    private int card; 

    public Card(int card) { 
     this.card = card; 
    } 

    public static Card makeCard(int i) { 
     return new Card(i); 
    } 

    public int getCard() { 
     return card; 
    } 
} 
+0

這似乎比它需要更復雜...我會給一個鏡頭,但我想用我自己的類和方法。我有一個重複,包含和添加方法。我不確定getCard()在你的解決方案中。 –

+0

編輯它添加卡類。它肯定比它應該更復雜:)生病看我能否用更短的版本來。 –