嗨,我正在尝试构建一个扑克ICM计算器,该计算器根据筹码量和支出结构确定每个玩家的期望值。当我在桌旁插入3个播放器时,它起作用,但是当我尝试4个播放器时,它会吐出不正确的值,并且我想尽办法找出原因。这是我的代码:
# starting vars
players_remaining = [ "p1", "p2", "p3" ]
players_remaining_stacks = [ 4500, 2700, 1800 ]
# first place pays $84, second $36
payouts = [ 84, 36, 0 ]
# calculate total chips among all players
total_chips = 0
for stack in players_remaining_stacks:
total_chips += stack
# STEP 1:
# create a list of all possible finish positions, each possibility has
# the remaining players finishing in a different order
possible_finish_positions = list(itertools.permutations(players_remaining, len(players_remaining)))
# STEP 2:
# Build matching list of possible_finish_probabilities
# to match possible_finish_positions, probability for each
# position in each scenario
possible_finish_probabilities = []
# loop through every permutation
for finish_positions in possible_finish_positions:
# % chance of each player finishing where they finish in this permutation
# this will get tacked onto possible_finish_probabilities when finished
perm_probabilities = []
# total amount of chips we've deducted for this permutation
perm_chips_deducted = 0
# loop through each finish position
for x in range(len(finish_positions)):
player_name = finish_positions[x]
index = players_remaining.index(player_name)
player_stack = players_remaining_stacks[index]
# the odds of this player finishing in this position is
# their chips divided by remaining chips
probability = player_stack / ( total_chips - perm_chips_deducted )
# add to the probabilities for this permutation
perm_probabilities.append(probability)
# deduct this player's chips from remaining chips
perm_chips_deducted += player_stack
possible_finish_probabilities.append(perm_probabilities)
# now we have two matching lists,
# possible_finish_positions and a matching possible_finish_probabilities
# STEP 3:
# we can now create the probabilities of finishing in each position for
# each player by looping through all of the scenarios for each player
finish_probabilities = []
# loop through each player
for player_name in players_remaining:
# initialize probability as 0 for this player
# finishing in each position
this_p_probabilities = []
for x in range(len(players_remaining)):
this_p_probabilities.append(0)
# loop through scenarios
for x in range(len(possible_finish_positions)):
# this permutation is one possible scenario
permutation = possible_finish_positions[x]
# determine where the player finishes in this scenario
position = permutation.index(player_name)
# initialize the probability as the probability
# for the player who finished first in this scenario
probability = possible_finish_probabilities[x][0]
# now if this player is not the player who finished first,
# need to adjust the probability by mutliplying it by
# the probability for every player in the scenario ahead of this
# player
if position != 0:
print("position not 0, adjusting")
# loop through everyone in front of this player
# in the scenario
for y in range(0, position):
# adjust the probability
probability *= possible_finish_probabilities[x][y + 1]
# if player is 1st in this scenario, their probability
# is set to this probability of finishing first.
# otherwise we add it to any other probabilities of the
# player finishing in this position
if position == 0:
this_p_probabilities[position] = probability
else:
this_p_probabilities[position] += probability
# finished probability for this player
finish_probabilities.append( this_p_probabilities )
print("finish_probabilities=")
for x in range(len(finish_probabilities)):
print(str(finish_probabilities[x]))
# now I can calculate the EV of each player
# multiply the probability of each position times the
# payout for that position
player_EVs = []
for x in range(len(finish_probabilities)):
# get the probability of player finishing
# in each position
probabilities = finish_probabilities[x]
EV = 0
# multiply probability of each position by the payout
# for that position
for y in range(len(probabilities)):
EV += probabilities[y] * payouts[y]
# store
player_EVs.append( EV )
print("player_EVs")
print(str(player_EVs))
令我发疯的是,此代码根据https://www.icmpoker.com/icmcalculator/#RXui处的ICM计算器为这3个玩家生成了正确的ICM EV值。但是,如果我将顶部的3个变量更改为:
players_remaining = [ "p1", "p2", "p3", "p4" ]
players_remaining_stacks = [ 4500, 2700, 1800, 1000 ]
payouts = [ 84, 36, 0, 0 ]
这将增加第4名玩家的场景,并且此处的EV值相差很大。特别是,当我在代码末尾附近输出finish_probabilities时,每个玩家的概率看起来都正确,因为他们先完成的概率很高,但是其他3个概率都关闭了,每个位置的概率加起来每个玩家都大于1。
我逐行梳理了这段代码,据我所知,它正在执行我认为应该执行的操作。我不知道为什么它对3个玩家正确,但是当我添加第4个玩家时它不起作用。任何帮助,将不胜感激谢谢。
感谢所有对此进行了审核的人。我相信我已经找到了问题,由于没有其他扑克ICM问题,我将其保留下来。
问题是,在某些情况下,我的计算概率是两倍。例如,对于4位玩家,玩家可以完成的顺序有24种排列,其中2个示例是
p1, p2, p3, p4
p1, p2, p4, p3
关于p2位居第二,我将这两种情况(以及p2位居第二的任何其他排列)的概率加在一起,以确定总数p2排名第二的概率。但是,实际上这是p1先完成两次,然后p2次完成两次,因此在计算p2的第二次放置概率时,计算中仅应包括其中的1个。]
[我插入代码以确保在计算p2时将第二名(或该场景中之前的其他玩家与其他场景相同的其他任何玩家)放置的概率只包括那些“相同”场景中的1个。
代码现在适用于所有玩家。谢谢