Java 21点极小极大算法
我正在用极大极小树实现一个21点游戏,它计算概率并根据概率自动进行游戏 假设我们玩一副牌,第一个游戏庄家拿:“5”,玩家拿“57”,所以玩家的总分是12分 在这种情况下,首先,我试图检查所有可能的可能性,为球员的立场的决定 如果球员站起来: 我在牌组中的剩余牌如下: 牌组结构(K,V)K:卡号,V:卡号Java 21点极小极大算法,java,python,algorithm,artificial-intelligence,minimax,Java,Python,Algorithm,Artificial Intelligence,Minimax,我正在用极大极小树实现一个21点游戏,它计算概率并根据概率自动进行游戏 假设我们玩一副牌,第一个游戏庄家拿:“5”,玩家拿“57”,所以玩家的总分是12分 在这种情况下,首先,我试图检查所有可能的可能性,为球员的立场的决定 如果球员站起来: 我在牌组中的剩余牌如下: 牌组结构(K,V)K:卡号,V:卡号 {1: 4, 2: 4, 3: 4, 4: 4, 5: 2, 6: 4, 7: 3, 8: 4, 9: 4, 10: 16} 现在,经销商应该超过17号。一些示例如下所示: 5(base ca
{1: 4, 2: 4, 3: 4, 4: 4, 5: 2, 6: 4, 7: 3, 8: 4, 9: 4, 10: 16}
现在,经销商应该超过17号。一些示例如下所示:
5(base card) + 1(11) + 1 = 17 (possibility of this hand : 4/49 * 3/48)
5(base card) + 1(11) + 2 = 18 (possibility of this hand : 4/49 * 4/48)
......
5 (base card) + 10 + 1 + 1 = 17 (possibility of this hand : 16/49 * 4/48 * 3/48)
我的问题是,我如何计算所有这些可能性,以及球员决定是否有效的最终可能性。我想不出如何对这些数字组合进行编码
编辑:
我找到了计算可能组合的代码。它和我长得很像。我需要改变我的问题,我希望我能做到这一点
def subset_sum(numbers, target, partial=[]):
s = sum(partial)
# check if the partial sum is equals to target
if s == target:
print "sum(%s)=%s" % (partial, target)
if s >= target:
return # if we reach the number why bother to continue
for i in range(len(numbers)):
n = numbers[i]
remaining = numbers[i+1:]
subset_sum(remaining, target, partial + [n])
if __name__ == "__main__":
subset_sum([3,9,8,4,5,7,10],15)
#Outputs:
#sum([3, 8, 4])=15
#sum([3, 5, 7])=15
#sum([8, 7])=15
#sum([5, 10])=15
这个游戏不是真的minimax的情况 在minimax中,两个玩家根据已知的位置进行移动,并在确定他们的最佳移动时考虑另一个玩家的移动 由于本例中有两名玩家,一名玩家(除了决定是否站立外,他实际上不会改变棋盘的状态)和一名庄家(他只是随机移动),处于未知棋盘状态,有随机选项,因此不能使用minimax 在这种情况下,一个相当有效的算法是从5开始,再加上7:
base = 5
cards = [7]
使用以下公式:
if sum(cards) + base < 16:
hit()
else:
if evalStand() > minStandChance:
hit()
如果总和(卡片)+基数<16:
hit()
其他:
如果evalStand()>minStandChance:
hit()
如果为true,则无需计算牌树,因为玩家无论如何都需要获得另一张牌
在那之后,得到站在那之后的概率:
def evalStand():
hand = base + sum(cards)
sums = []
for cardValue, count in cards.items():
for i in range(count):
sums.append(cardValue + hand)
return len([i for i in sums if i <= 21])/float(len(sums))
def evalStand():
手牌=基数+总和(卡片)
总和=[]
对于cardValue,计入卡片。项()
对于范围内的i(计数):
追加金额(cardValue+hand)
返回len([i代表i的总和,如果i你是正确的,因为游戏的随机性,minimax不适用,但是有一个变量称为expectimax,它是专门为这种情况开发的。你的解决方案有两个常量(16和minStandChance),它模拟了“经验法则”不是正确地模拟游戏的实际状态。@NickLarsen当你说应该使用expectimax时,你的意思是平均事件是处于17-21总和窗口中的机会,并且玩家选择是停留还是不停留?我不认为expectimax比我之前所说的更准确地模拟情况dy,因为玩家对牌的总数没有影响,所以计算超过1张牌是没有意义的。根据简单的游戏规则,这个游戏严格的机械游戏排除了使用决策策略,而不仅仅是继续下去是否有益。事件代表状态变化;在这种情况下,汽车在一场游戏中,即使是两名玩家之间,也可能有多个ds。经验法则是在大多数情况下都是正确的启发法,而不一定总是正确的。Black jack足够复杂,我认为命中16次或更少在至少一种情况下都是错误的,几乎可以肯定的是,你不会找到f值或者minStandChance总是100%正确。如果有,你应该将它添加到你的解决方案中。@NickLarsen我现在明白了。16是一条规则(就我所玩的和理解的而言),但是minStandChance
是一个启发性的,应该加以解释。谢谢你向我指出。我已经更新了我的答案。