我正在用minimax树实现一个二十一点游戏,它计算概率并自动依赖于这个概率。
假设我们玩1套牌,第一个游戏经销商需要:' 5 '和玩家需要' 5 7 '所以球员的总得分为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 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
答案 0 :(得分:0)
这场比赛对于极小极大赛来说并非如此。
在极小极大情况下,两名玩家根据已知位置进行移动,并考虑其他玩家在确定其最佳移动时的移动。
由于这个例子有两个玩家,玩家(他实际上并没有移动,因为他改变了董事会的状态,除了决定是否站立)和经销商(只做随机移动),具有随机选项的未知板状态,特别是minimax不能使用。
在这种情况下,一个运行得相当好的算法将是从5和添加的7开始:
base = 5
cards = [7]
使用以下公式:
if sum(cards) + base < 16:
hit()
else:
if evalStand() > minStandChance:
hit()
没有必要在真实时计算卡片树,因为玩家无论如何都需要获得另一张卡片。
之后,获得站立后的概率:
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))
简单地过滤掉仍然可以获得玩家的可能牌的比率&lt; = 21.这个游戏中常用的策略是爬上21号。这就模仿了它。如果在下一轮之后站立的概率小于0.5,则玩家可以停止获得牌。
同样,这种情况对minimax来说并不好,但这应该是一个很好的替代解决方案。
修改强>
正如@NickLarsen所指出的那样,minStandChance
代表了一种启发式方法。没有一个100%准确的变量,但可以根据您希望AI玩多少风险进行调整。 (接近0是有风险的,接近1是保守的)。