如何调试我的扑克游戏递归逻辑?

时间:2017-03-02 18:49:55

标签: java recursion

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处捕获所有指针并在那里终止它,因此我不会看到代码如何在函数的其余部分执行。

4 个答案:

答案 0 :(得分:1)

你的班级应该用空手接收堆栈溢出。 你将新卡(0)发送到手上。这是补充。 然后再次拨打下一个添加 - 以及&#39; for&#39;再次从0开始。检查添加1.然后从0开始 - 它在那里,不添加任何东西并重新开始。从0开始的地方。什么都不做。从0开始.Ad infinum - &gt;计算器。

每次完成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;
    }
}

答案 1 :(得分:0)

最初,h(大概)是空的。所以addNext会循环遍历所有可能的卡片,并且因为它们都不在手中,所以无论手中当前有多少张卡片都将每张卡片都添加到手中。

答案 2 :(得分:0)

在我看来,你的for循环最终会增加整个牌组。

答案 3 :(得分:-1)

在循环中运行52次迭代。在每次迭代中,您(有条件地)将卡添加到手中,然后递归调用您的函数。但是在递归调用返回后,你进入下一次迭代并再次向手中添加一张卡片。

这样就可以限制卡#5;这里没有任何限制。