Неверный покер калькулятор ICM в Python - PullRequest
0 голосов
/ 16 марта 2020

Привет. Я пытаюсь создать калькулятор Poker 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))

Что сводит меня с ума, так это то, что этот код генерирует правильные значения EV ICM для этих 3 игроков согласно калькулятору ICM на https://www.icmpoker.com/icmcalculator/#RXui. Однако, если я изменю 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-го, это не работает. Спасибо за любую помощь, спасибо.

1 Ответ

0 голосов
/ 16 марта 2020

Спасибо всем, кто это просмотрел. Я считаю, что нашел проблему, и я оставлю ее в курсе, поскольку не вижу других вопросов по ICM в покере.

Проблема в том, что в некоторых ситуациях у меня было двойное вычисление вероятностей. Например, с 4 игроками, есть 24 перестановки ордеров, которые игрок может завершить sh, и 2 из этих примеров

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

С точки зрения финишной секунды p2, я складывал вероятность обоих из этих сценариев ios (а также любая другая перестановка, где p2 заканчивается вторым), чтобы определить общую вероятность того, что p2 закончится вторым. Однако на самом деле это p1, заканчивающий первым, и p2, заканчивающий второй дважды, так что только 1 из них должен быть включен в вычисление при вычислении вероятности размещения второго p2.

Я вставил код, чтобы гарантировать при вычислении вероятности размещения второго p2 (или любого другого игрока, где игроки перед ними в сценарии идентичны некоторому другому сценарию), чтобы включить только один из этих «идентичных» сценариев ios.

Код теперь работает для любых игроков. Спасибо

...