找到所有可能的二十一点牌的算法
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 开头。
如果这个解释不是很清楚,我很抱歉。我被卡住了,所以任何关于如何让这个递归正常工作的帮助将不胜感激。谢谢!
这里有很多问题。
for card in deck
- 您正在遍历一个列表,然后从中删除对象。这是让事情无法正常工作的好方法。
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)
我正在尝试在 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 开头。
如果这个解释不是很清楚,我很抱歉。我被卡住了,所以任何关于如何让这个递归正常工作的帮助将不胜感激。谢谢!
这里有很多问题。
for card in deck
- 您正在遍历一个列表,然后从中删除对象。这是让事情无法正常工作的好方法。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)