редактировать Похоже, я получаю разные ответы о том, как работает игра, и после прочтения официальных правил и общения с многочисленными друзьями по покеру, я думаю, что сам не знаю правил. Любое разъяснение будет оценено.
Я работаю над небольшой покерной игрой в MSVC ++ 2010 Express и застрял, пытаясь придумать способ кодирования системы sub pot. По какой-то причине я не могу понять, как это должно работать, и мне было интересно, может ли SO опубликовать какие-то способы сделать это. Вот особая ситуация, которая может и, скорее всего, произойдет в игре в Техасский Холдем.
Ситуация:
У игрока А есть первое действие с фишками 50 долларов, и он решает пойти ва-банк. Игрок Б рейзит до 150 долларов. Игрок C имеет фишки всего на $ 70 и решает пойти олл-ин. Игрок D имеет только $ 20 и идет олл-ин. Теперь, как я могу изобрести механизм дополнительного банка, чтобы отслеживать все это.
Из того, что я понимаю, что произойдет:
Игрок А создает основной банк с $ 50. Вы комбинируете B и C по $ 50, чтобы сделать основной банк $ 150. Затем вы берете оставшиеся у Игрока $ 100 и делите их на $ 80 и $ 20. Затем вы делаете дополнительный банк для Игрока B и C на сумму 40 долларов (остаток игрока C от 70 долларов), а затем вы возвращаете синус Игрока B на сумму 80 долларов, которую никто не может покрыть. Ставка 20 $ игрока D переходит в игрока B, а дополнительный банк Cs $ 40 теперь стоит $ 60. *(или это не добавляется? Не добавляется ли оно к какой-либо ставке, поскольку не может покрыть основной банк в размере $ 50, если так, то они не добавляются ни к чему *
Теперь, когда дело доходит до оценки. Если игрок A выигрывает, он выигрывает 150 долларов у игроков A, B и C. Далее, игроки B, C и D идут на это со своим поддотом стоимостью 60 долларов.
Если игрок B выигрывает, он выигрывает все.
Если игрок C выигрывает, он выигрывает 150 долларов у игроков A, B и C. Затем он бросает вызов игроку B и D за 60 долларов.
Игрок D может выиграть только $ 60, в то время как кто-то уже выиграл бы банк Игрока A, B и C, когда он опустится так далеко. (зависит, будет ли это добавлено или нет к банку B и C, поскольку он не покрывает основную ставку в 50 $)
Это как все должно работать? Я с трудом пытаюсь понять, как я могу отслеживать каждую ставку и суб-банк. Любые идеи или логические способы их реализации очень помогли бы. Спасибо за ваше время. 🙂
Я думал о том, чтобы каждая ставка была уникальным идентификатором, или, может быть, у каждого раунда есть идентификатор, и я добавлял каждую ставку в массив для оценки, который также указывает на контейнер с информацией об игроке. Я также должен принять во внимание, что некоторые игроки могут быть в поддотах, а также уже в раздаче и сбрасывать, что означает, что я тоже должен отслеживать это.
В этом примере и основной, и боковой банки рассчитаны неверно.
ПРАВИЛО: Правящий принцип заключается в том, что каждый игрок ставит столько же ставок противника, сколько он оставил в своем стеке.
Расчет:
1) Сначала рассмотрим игрока с наименьшим стеком (который пошел ва-банк). В текущем примере это игрок D с $ 20.
2) Далее мы суммируем $ 20 с каждого игрока (A, B, C, D) и основной банк формируется равным $ 80, он оспаривается всеми игроками.
3) Фишки игроков остались A — 30 долларов, B — 130 долларов, C — 50 долларов, D — 0 долларов.
4) Далее мы рассмотрим второй наименьший стек, в текущем примере это игрок А, у которого осталось $ 30. Боковой банк 1 формируется равным 30 (A) + 30 (B) + 30 (C) = 90 долларов. Игрок D не может выиграть этот побочный банк, так как у него закончились деньги.
5) Фишки игроков остались A — 0 долларов, B — 100 долларов, C — 20 долларов.
6) Боковой горшок 2 формируется равным $ 20 (B) + $ 20 (C) = $ 40. Игрок А не может выиграть этот побочный банк, так как у него закончились деньги.
7) Игроку B осталось $ 80, эта сумма возвращается ему.
Итак, мы наконец получаем:
Основной банк = $ 80, оспаривается всеми игроками A, B, C, D
Side pot1 = 90 $, оспаривается A, B, C
Side pot2 = 40 $, оспаривается B, C
80 долларов возвращается игроку Б
Ваш пример говорит сам за себя. Подпот создается либо по первой ставке, либо каждый раз, когда ставка отличается от начальной ставки. Есть несколько свойств:
Итак, идея для класса Subpot:
amount = amount1 + amount2
;Каждый раз, когда добавляется новая ставка, сначала делите разницу, затем объединяйте банки с одинаковым количеством.
т.е.
//laughable attempt
class Subpot{
int amount; //oops i mean bet
int pot; //actually function = amount x participants
std::vector<Players*> participants;
bool split(int amounta, int amountb, Subpot& a, Subpot& b);
static bool merge(Subpot& a, Subpot& b , Subpot& dest);
}
Теперь каждый раз, когда появляется новая рука, вы берете предыдущий стабильный набор поддотов и создаете следующее поколение поддотов.
Я бы сделал так, чтобы сделать отдельный контейнер, в котором хранятся сделанные ставки, отслеживая, кто и сколько поставил.
std::list<std::map<PlayerID, Chips>> wagers;
unsigned n_raises; // to keep track of number of raises, useful in limit holdem
Я предполагаю, что у вас есть список / массив активных игроков в руке.
Теперь, если игрок делает колл, вы просто вставляете его ID и количество фишек в карту, которая находится в конце списка.
Если игрок делает рейз, вы вставляете ID и соответствующее количество фишек на карту, которая находится в конце списка, а затем отталкивать другая карта. Вы вводите сумму, поднятую в этой новой спине. Обновить n_raises
а также to_call
соответственно.
При вставке ставки игрока, вам нужно выполнить итерацию с начала списка и начать вставку, когда вы впервые сталкиваетесь с картой, на которой нет фишек от этого игрока. Впереди может быть несколько рейзов, поэтому вы не всегда можете просто вставить последнюю карту.
Сложный случай, когда у игрока недостаточно фишек для покрытия полного колла. В этом случае вы найдете карту, где он раздает фишки, вставить новая карта сразу после нее и передача всех фишек (других игроков), которые игрок не смог покрыть на этой новой карте. (Мы не обновляем n_raises
в этом случае).
Вот как все это будет выглядеть для 4 игроков A, B, C, D:
Player A bet 100
map0: (A,100)
Player B calls:
map0: (A, 100) (B,100)
Player C raises to 300:
map0: (A, 100) (B,100) (C,100)
map1: (C, 200)
Player D calls:
map0: (A, 100) (B,100) (C,100) (D,100)
map1: (C, 200) (D,200)
Player A's turn, he folds.
Player B calls, but he's got only 50 left:
map0: (A, 100) (B,100) (C,100) D(100):
map1: (B, 50) (C, 50) (D,50) <--- here we have split the map in two
map2: (C, 150) (D, 150)
The betting round is over.
Вы можете иметь отдельный список для каждого раунда ставок или только один и сохранить копию итератора для начала нового раунда.
Теперь легко разделить банк. Вы определяете лучшую руку и просто начинаете совать карты в начале списка, пока игрок с лучшей рукой участвует в карте. Если после этого список пуст, все готово. В противном случае определите вторую лучшую руку и повторите.
В приведенном выше примере, если у игрока B окажется лучшая рука, вы нажимаете на него map0 и map1. map2 будет идти к победителю C и D.
Давайте попробуем ваш пример:
У игрока А есть первое действие с фишками 50 долларов, и он решает пойти ва-банк. Игрок Б рейзит до 150 долларов. Игрок C имеет фишки всего на $ 70 и решает пойти олл-ин. Игрок D имеет только $ 20 и идет ва-банк.
map0: (A,50)
---------------------
map0: (A,50) (B,50)
map1: (B,100)
---------------------
map0: (A,50) (B,50) (C, 50)
map1: (B,20) (C,20)
map2: (B,80)
--------------------
map0: (A,20) (B,20) (C,20) (D,20)
map1: (A,30) (B,30) (C,30)
map2: (B,20) (C,20)
map3: (B,80)
Я думаю, что это очень похоже на то, как мы это делаем за реальным покерным столом, и я бы, вероятно, подошел к этому так, если бы мне пришлось писать покер. Надеюсь, поможет 🙂