首页 > 解决方案 > 找到所有可能的二十一点手的算法

问题描述

我正在尝试在 Python 中编写一个函数,该函数采用牌值列表和玩家手中的值列表,并将返回玩家最终可能获得的所有可能手牌的列表,其值为 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”开头,那么第一个将carddeck另一个 2。另一张牌被抽出来,因为我们还没有 17,它是另一个 2。这很好。我们现在有 16 张,所以从牌堆中取出另一张牌,也就是最后两张(牌是按顺序排列的)。我们现在有 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 开头。

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

标签: pythonalgorithmrecursionblackjackplaying-cards

解决方案


这里有很多问题。

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

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

为了解决这个问题,对于此类问题,您可能希望在递归函数中制作“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)

推荐阅读