找到所有可能的二十一点牌的算法

Algorithm to find all possible blackjack hands

我正在尝试在 Python 中编写一个函数,该函数获取纸牌值列表和玩家手中的值列表,并将 return 所有可能手牌的列表玩家最终可以得到 17 或更高的值。卡片由与卡片值相对应的整数表示(2-10,A 始终为 11。所有花牌都值 10)。这是我尝试编写的功能。 deck 是一个整数列表,表示仍然在牌组中的牌(缺少 3 张牌,2 张在玩家手中,1 张给庄家)。 runninglist 是一个整数列表,代表玩家手中的牌。 playerPossibilities 是总点数为 17 或更高的手牌列表。

def simPlayerHelper(deck, runningList, playerPossibilities):
    for card in deck:    
        runningList.append(card)
        if sum(runningList) > 16:
            temp_rl = runningList.copy()
            playerPossibilities.append(temp_rl)
            runningList.remove(card)
        else:
            deck.remove(card)
            simPlayerHelper(deck, runningList, playerPossibilities)
    for x in playerPossibilities:
        print(x)

递归无法正常工作。比如runningList以“10”和“2”开头,那么deck中的第一个card会是另一个2,又抽一张牌,因为我们没有17然而,它是另一个 2。这很好。我们现在有 16 张,所以从牌组中取出另一张牌,也就是最后 2 张(牌是按顺序排列的)。我们现在有 18 个,所以 [10,2,2,2,2] 被添加到 playerPossibilities。然后添加 [10,2,2,2,3](一副牌中四个 3 的四次),[10,2,2,2,4](四次),依此类推。那也行。但现在我需要它返回到手牌中的第四张牌,如果那张牌是 3、4、5 等等,则排除所有可能性。然后回到第三张牌,如果那张牌是 3,然后是 4,然后是 5,则找出这副牌中所有剩余牌的可能性。现在,它只是循环遍历手中的最后一张牌,所以 playerPossibilities 中的所有项目都以 10,2,2,2 开头。

如果这个解释不是很清楚,我很抱歉。我被卡住了,所以任何关于如何让这个递归正常工作的帮助将不胜感激。谢谢!

这里有很多问题。

  1. for card in deck - 您正在遍历一个列表,然后从中删除对象。这是让事情无法正常工作的好方法。

  2. if // else - 你抓一张牌,把它放在你的手上,然后检查你的获胜条件。如果超过 16,记录答案,从你的手上移开并继续。伟大的!如果不超过 16,请进行递归...但是在递归完成后,您没有将牌从手中移除的机制。 (我相信这是您当前错误的来源)

为了解决这个问题,对于这类问题,您可能需要在递归函数中复制“deck”,这样子调用就无法从父 deck 中取出卡片(您没有从父 deck 中取出卡片)检查他们)。您还想确保在每次迭代后将卡片从您的手中移除。我可能会建议像这样做你的循环

def run_sims(deck):
  current_deck = copy(deck)
  while current_deck:
    card = deck.pop()
    current_hand.append(card)
    # do logic / recurse
    current_hand.pop(card)