扑克ICM计算器在Python中不正确

问题描述 投票:0回答:1

嗨,我正在尝试构建一个扑克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个玩家时它不起作用。任何帮助,将不胜感激谢谢。

python poker
1个回答
0
投票

感谢所有对此进行了审核的人。我相信我已经找到了问题,由于没有其他扑克ICM问题,我将其保留下来。

问题是,在某些情况下,我的计算概率是两倍。例如,对于4位玩家,玩家可以完成的顺序有24种排列,其中2个示例是

p1, p2, p3, p4
p1, p2, p4, p3

关于p2位居第二,我将这两种情况(以及p2位居第二的任何其他排列)的概率加在一起,以确定总数p2排名第二的概率。但是,实际上这是p1先完成两次,然后p2次完成两次,因此在计算p2的第二次放置概率时,计算中仅应包括其中的1个。]

[我插入代码以确保在计算p2时将第二名(或该场景中之前的其他玩家与其他场景相同的其他任何玩家)放置的概率只包括那些“相同”场景中的1个。

代码现在适用于所有玩家。谢谢

© www.soinside.com 2019 - 2024. All rights reserved.