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

Сразу оговорюсь, что я в покер не играю, и знаю его хуже чем те, кто играет свои первые партии в жизни. Но может это не так уж и важно?

Рассматриваю тот покер, где в колоде 52 карты: 2-10, В, Д, К, Т и 4 масти. Вероятно это Техасский Холдем. На столе в последнем круге пять карт, и по две карты у игроков.

При написании программы расчетов использовался проект https://github.com/lvandeve/oopoker, из него были взяты модули card.h/cpp & combination.h/cpp - так я сумел обойти необходимость знать нюансы комбинаций покера.

Прикрепленная моя программа выглядит вот так:

Что здесь что обозначает и почему именно так, это нужно вчитываться в смыслы статьи. Итак, как здесь что считается...

Простейший абстрактный случай - все всегда доигрывают

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

Колода это выборка с изъятием, из них при начальном раскладе известны 5 карт - 3 на столе и 2 на руках, и 47 не известны. У каждого из соперников есть две неизвестных карты. При последующих кругах на стол добавляются еще две карты, итого становится известно о 7 картах.

В общем, из одного обсчитываемого начального расклада, нужно много-много раз смоделировать случайный выбор с изъятием двух карт для соперника, и двух карт для стола из 47 неизвестных карт, и исходя из получившихся раскладов, считать чья комбинация сильней - своя или расклад соперника. Сопернику ли сначала добавлять карты или на стол - здесь это не важно, но потом будет важно, поэтом сразу думаем что сначала добавили сопернику, потом на стол.

При таких генерациях, получится, что если было N - количество сгенерированных партий, и W из них выигрышных, тогда W/N - вероятность выигрыша нашего обсчитываемого расклада.

Если сделать такую генерацию хотя бы 1000 раз, то думаю средняя вероятность выигрыша будет достаточно достоверна. Для современного рядового десктопа это займет ничтожные доли секунды.

Примерно таким алгоритмом:

using ListCards = vector<IdxCard>; // IdxCard: int 0..51

struct ResProb {
    int cAll = 0;
    int cWin = 0;
    int cLoss = 0; // cAll - cWin - cLoss = кол-во ничьих

    double probWin() const { return FDIV(cWin, cAll); }
    double probLoss() const { return FDIV(cLoss, cAll); }
};

ResProb calcProbability(
        Deck& deck, // колода с механизмом изъятия
        const ListCards& myHand, // карты у меня на руках
        const ListCards& srcDesk, // карты на столе, пока здесь 3 штуки
        int cInterate = 1000) {

    ResProb r;

    for (; r.cAll < cInterate; ++r.cAll) {
        int c = calcOneRandomVariant_genAlienAndDesk(
                   deck, myHand, srcDesk, check);
        if (c > 0)
            ++r.cWin;
        else if (c < 0)
            ++r.cLoss;
    }

    return r;
}
Использованные механизмы и функции (в исходниках они чуть усложнены чем здесь):
// этот класс представляет собой колоду с изъятием.
struct Deck {

    ListCards residueDeck;

    // изъять одну случайную карту
    IdxCard takeRandom();
    // изъять несколько случайных карт
    ListCards takeRandomCount(int cnt);

    // вернуть в колоду карту
    void recall(IdxCard card);
    // вернуть в колоду несколько карт
    void recallList(const ListCards& cards);
};

// соединяет два множества карт рука и стол, и считает
//  лучшу покерную комбинацию
Combination getConcatCombo(
        const ListCards& cards1, const ListCards& cards2) {

    vector<Card> nativeCards;
    nativeCards.reserve(cards1.size() + cards2.size());

    for (const IdxCard& card: cards1)
        nativeCards.push_back(Card(card));

    for (const IdxCard& card: cards2)
        nativeCards.push_back(Card(card));

    // вызов функции из проекта oopoker:
    //   - расчет лучшей комбинации на основе расклада
    Combination res;
    getCombo(res, nativeCards);
    return res;
}

// достраивает srcDesk до 5 и сравнивает результат.
int calcOneRandomVariant_genDesk(
        Deck& deck,
        const ListCards& myHand,
        const ListCards& alienHand,
        const ListCards& srcDesk) {

    int szSrcDesk = srcDesk.size();

    // 1. достраивает desk до 5, если desk меньше
    ListCards newDesk(srcDesk);
    while (newDesk.size() < 5)
        newDesk.push_back(deck.takeRandom());

    // 2. расчет комбинаций
    Combination myCombo = getConcatCombo(myHand, newDesk);
    Combination alienCombo = getConcatCombo(alienHand, newDesk);

    // 3. возвращает карты в колоду - на выходе колода
    //    будет как на входе
    for (int ii = szSrcDesk; ii < newDesk.size(); ++ii)
        deck.recall(newDesk.at(ii));

    // 4. сравнение комбинаций
    //      - вызов функции из проекта oopoker
    return compareCombo(myCombo, alienCombo);
}

// генерирует расклад противника,
//   и после вызывает генерацию расклада стола,
//   а после сравнивает результат с нашим раскладом
int calcOneRandomVariant_genAlienAndDesk(
        Deck& deck,
        const ListCards& myHand,
        const ListCards& srcDesk) {

    // 1. генерирует расклад противника
    ListCards alienHand = deck.takeRandomCount(2);

    // 2. достраивает стол
    int r = calcOneRandomVariant_genDesk(
              deck, myHand, alienHand, srcDesk);

    // 3. возврат в колоду противника
    deck.recallList(alienHand);

    return r;
}

Получилось, что для любого начального расклада можно посчитать некую абстрактную вероятность. Если соперников двое или более, то просто возводим в степень нашу вероятность количеством соперников, т.к. это простое условие И - нам нужно выиграть всех соперников, каждый из которых имеет случайный расклад.

Если нагенерировать много-много случайных начальных раскладов, и для каждого посчитать такую вероятность, то можно нарисовать график распределения вероятностей выигрыша - для наглядности, и для того, чтобы посмотреть на это и подумать "и как это раньше играли в такое без компьютеров":

Ось Х: 0..1 - вероятность выигрыша, Ось Y это график плотности вероятности.
Ось Х: 0..1 - вероятность выигрыша, Ось Y это график плотности вероятности.

Кривая получилась не симметричная и несколько ломанная, несмотря на то, что было обсчитано порядка 100тыс раскладов. Но и суть раскладов это то же нечто дискретное и не упорядоченное. Генерацию этого графика можно увидеть здесь.

Повышаем точность расчета: отказ соперника от игры

Соперник иногда отказывается от игры при своем текущем раскладе. Это происходит когда у него на руках расклад с низкой вероятностью выигрыша, или может по причинам предрассудков или коварных планов обмануть соперников.

Если соперник отказался, значит игры не было. Значит такие расклады, от которых систематически отказывается соперник, не влияют на среднюю реальную вероятность выигрыша. Здесь я говорю только про отказы сделанные до совершения первой ставки.

В основном отказываются по причине плохого расклада - когда расклад имеет низкую вероятность выигрыша, и такое можно прописать в правила генерации расклада соперника. Попросту возьмем и отбросим из генерации все расклады соперника, когда его абстрактная вероятность ниже 0.4.

Получается, что нам нужна генерация в генерации. Верхний уровень будет симулировать генерацию псевдо-реальной вероятности, а второй уровень абстрактной вероятности будет решать, которые из раскладов войдут в верхний уровень.

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

Замечу только, что количество вариантов начальных комбинаций это 52*51*50*49*48 = ~300млн. Это не большое количество для компьютеров, можно сохранить предрасчитанные варианты в памяти и использовать для дальнейших расчетов. Так же можно уменьшить размер индекса за счет частичной сортировки - первые две сортируем, и последующие три сортируем раздельно. И за счет нивелирования влияния мастей. Но тут нужно очень задуматься какая точная формула для расчета количества вариантов.

Расчет с отбрасыванием части раскладов противника представлен в исходниках в функции calcPseudoRealProbability. Там используется второй раз вложенный вызов calcProbability для определения вероятности расклада противника. Функция получилась вроде не большая, но заморочнная по смыслу, поэтому сюда ее напрямую не вставляю, но думаю особо интересующиеся и дотошные разберутся.

В общем, в прикрепленной программе в закладке "Расчет" можно указать любую вероятность, при ниже которой противник якобы отказывается играть, и считать с учетом отбрасывания таких вероятностей.

Еще больше уточняем вероятность выигрыша начального расклада

Таблиц с сохраненными реальными играми у меня нет, а все дальнейшие шаги они основываются уже на статистике игры, а не просто комбинаторных свойствах колоды карт.

Но если бы были такие таблицы, то можно... Во первых первое простое уточнение - сколько именно раскладов отказывается от игры.

Количество раскладов в игре это количество участников. Суммируем их по всем играм, и обозначим буквой P (persons).

Подсчитываем количество раскладов с отказом без ставки - так же по отдельности каждого игрока и во всех играх, и обозначим буквой C (cancellation).

Тогда вероятность отказа будет C/P. Эта цифра это не сама абстрактная вероятность отказа!!! Это площадь графика распределения вероятности приведенного выше. Отсчитываем такую площадь на том графике с левой стороны, и получаем точку на графике. И это уже и будет тот уровень абстрактной вероятности, при котором в среднем игроки отказываются от игры.

Такой расчет можно произвести в прикрепленной программе на закладке "Распределение". Выставить вероятность реальных отказов, и по нажатию "Сделать график распределения" и тогда в том числе будет рассчитан уровень таких абстрактных вероятностей. И после это значение применять на первой закладке "Расчет" для обсчета раскладов.

Еще чуть-чуть уточняем и залезаем в дебри распределений

Для дальнейшего уточнения начального расклада нужно уже воспроизводить процесс с точностью до распределений, а не только простым отсечением раскладов всех которые хуже некой черты.

Если собрать все отказы в виде распределения по вероятностям выигрыша, и наложить на график распределения всех комбинаций вероятностей выигрыша, то получим наверное нечто подобное этому:

Красным это я предположил какое будет распределение отказов.
А черным, это прежний же график распределения, только с меньшим дроблением.
Красным это я предположил какое будет распределение отказов. А черным, это прежний же график распределения, только с меньшим дроблением.

График распределения отказов накладывается умноженным на вероятность всех отказов от всех раскладов.

И тогда, при генерации расклад противника оценивается на отсечение как вероятность, что-то типа такого:

bool checkCancelAlienCards(
        const Distrib& distrWin,
        const Distrib& distrCancel,
        double allProbCancel,
        double probAlienWin) {

    double denWin = distrWin.getDensityByProbabilityX(probAlienWin);
    if (!denWin)
        return false;

    double denCancel = distrCancel.getDensityByProbabilityX(probAlienWin);
    double probOfCancel = (denCancel * allProbCancel) / denWin;

    if (FDIV(rand(), RAND_MAX) <= probOfCancel)
        return true; // вероятностным образом отбросили расклад противника

    return false;
}

Для этого кусочка кода, описание класса Distrib здесь, но сам этот метод не включен в исходники. Только здесь

Деньги вместо вероятностей

Здесь и дальше я буду делать только теоретические рассуждения и описания, не вдаваясь в детали. Программной части для этих этапов я не делал.

В покере нужно выбирать не только вероятность выигрыша, но и сколько денег на этой вероятности можно заработать. Можно часто и понемногу выигрывать, но редко и по много проигрывать. Или наоборот.

Чтобы избежать проигрыша в деньгах, нужно чтобы генерационная программа суммировала не только вероятности, или даже вместо вероятностей, нужно просто суммировать предполагаемые выигрыши-проигрыши в деньгах.

И тогда средняя сумма, которая будет состоять из суммированных сумм деленных на количество таких сумм, будет средним выигрышем-проигрышем на игру.

Опять же, на основании таблиц сохраненных игр, нужно строить распределения ставок в зависимости от успешности карт противника. И при генерации вариантов игры, сгенерированную комбинацию противника заменять на сумму денег соответствующую его успешности карт.

Величину денег можно считать не в абсолютной величине, а в относительной от начальной ставки. И соответственно суммарный выигрыш-проигрыш будут в относительных величинах.

Что дальше? - Моделирование процесса игры

Дальше нужно делать генерацию процесса игры, а не только начальных раскладов.

Нужно в предыдущем процессе моделирования, после сгенерированного расклада противника, от которого виртуальный противник не отказался, от него начинать генерировать последующие возможные действия противника.

Опять же, нужны таблицы сохраненных игр - реальных или тестовых приближенных к реальности - и из них считать, с какими вероятностями при каких раскладах происходят события отказа от игры, поддержания ставки и повышения ставки. И с такими вероятностями производить эти события в этой симуляции, согласно генератору случайных величин.

Стратегия нашего хода

Когда процесс симуляции доходит до нашего хода, то нужно вместо рандомной генерации, посчитать как будет развиваться игра в зависимости от всех возможных наших действий. И выбрать наилучший для нас вариант.

В коментариях подсказали, что это дерево решений. Но в отличии от классического дерева решений, здесь его нужно отстраивать на каждый шаг заново. Мне это напомнило q-learning, но там то же значительные отличие от нужного здесь процесса.

В общем, если по простому, и если есть много вычислительных ресурсов, то просто обсчитываем все варианты наших действий к каким последствиям они приводят.

Если поточнее, то нужно от текущего состояния игры, которая находится на этапе нашего хода, запустить рекурсивно множественную генерацию ситуаций. Обсчитать множественно каждый вариант нашего хода, и выбрать максимальный.

У таких обсчетов возможные варианты развития событий это только генерации случайных ходов противника, и докладывание двух карт на стол. Здесь существенно меньше вариантов, чем обсчет от начального состояния, и потому это все же вроде реализуемо по объему вычислений на каждый из вариантов нашего хода.

Заключение

Здесь последние главы я делал не детально. Но в принципе при желании в подобном направлении не сложно проработать алгоритм до практической реализации. Используя только механизмы общего направления, без закладывания специальных стратегий покера. Такая реализация, это скорее муторная и объемная вещь, чем что-то сверхсложное. Реализация выигрывающей программы в покер для меня не является особым интересом, и в свободное время я лучше буду изобретать свои алгоритмы прогнозирования общего направления, чем покерного.

При обсуждении с клиентом, в чем состоит игра, в один момент они мне упомянули, что есть ситуации, что если у нас на руках какой-либо специфичный расклад, то это уменьшает количество вариантов расклада соперника. Я же подумал, что это естественное следствие использования выборки с изъятием, и не стал останавливаться на вопросе.

Но может так и со всеми выигрышными стратегиями под покер? Может быть что любые лучшие стратегии будут естественным следствием использования описанного в статье механизма? Может оно будет работать чуть подольше без таких стратегий, но тем не менее будет и местами даже качественней? Потому что просто посчитает вероятности...

Дальше качество реализации и игры упирается в наличие достоверной статистики прошедших игр. А у кого больше всего такой статистики? Конечно же у тех, кто создает порталы по игре в онлайн покер. Поэтому, даже если у них совсем правильные генераторы случайных раздач карт, если они сами не могут подсмотреть карты, то это все не означает, что они не могут сами там играя всех выигрывать используя накопленную статистическую информацию или снабжать ею узкий круг людей.

В коментариях мне еще упоминули про оценку погрешности при подобных генерационных методах. И именно про оценку подобных методов у меня написано в предыдущей статье.

Комментарии (30)


  1. lgorSL
    04.09.2021 11:05
    +1

    Если сделать такую генерацию хотя бы 1000 раз, то думаю средняя вероятность выигрыша будет достаточно достоверна.

    Погрешность такой оценки будет примерно равна корню из одной тысячной - примерно 3%

    Получилось, что для любого начального расклада можно посчитать некую абстрактную вероятность. Если соперников двое или более, то просто возводим в степень нашу вероятность количеством соперников, т.к. это простое условие

    Приблизительно так, а математически вряд ли. Например, если у первого соперника слабые карты, то у второго соперника вероятность слабых карт чуточку меньше.

    И ещё для большинства комбинаций масть вообще не важна, и тогда количество вариантов для перебора будет сильно меньше. Мне интуитивно кажется, что вероятность выпадения двойки или тройки одинаковых карт можно точно посчитать.


    1. victor79 Автор
      04.09.2021 12:47

      примерно равна корню из одной тысячной

      Оценка такой погрешности считается как квантиль по бета-распределению, и равен он будет такому корню только при существенно определенном значении квантиля.


  1. GomboTs
    04.09.2021 11:14
    +17

    Послушайте, но изобретать велосипед с нуля в области, где люди сделали уже очень и очень много - это несколько наивно, вам не кажется?

    Калькулятор априорных вероятностей для покера - вещь совершенно базовая, ею сейчас пользуются примерно все. Статистика по играм противника - тоже.

    Надо идти дальше.


    1. victor79 Автор
      05.09.2021 14:42

      Надо идти дальше.

      Согласен, нужно идти. Но зачем мне идти в покер? Я описал принцип, который может быть применен к широкому кругу задач, а не только в покере. И именно этим он был интересен.


  1. Voila2000
    04.09.2021 11:46
    +3

    Не хочу показаться занудой, но я бы начал решение задачи с более подробного изучения предметной области. Есть огромное количество материала, например отличные книги Дэна Харрингтона. Там есть описание победного алгоритма.
    Статистика прошедших игр может быть интересна для изучения только если вы играете с более менее постоянным контингентом людей, игроков любителей. Для новых, неизвестных партнеров она бесполезна.


  1. edogs
    04.09.2021 12:51
    +3

    В заключении хочу сказать, что в принципе, реализация программы выигрывающей в покер, это скорее муторная и объемная вещь, чем что-то сверхсложное. И все упирается в наличие достоверной статистики прошедших игр.
    Чисто абстрактно — в ситуации когда играет куча обычных игроков и тут Вы зашли с алгоритмом — да, реализация возможна.
    На практике — на любом покер-сайте играет огромное количество ботов, поведение которых вычислить невозможно (в том числе потому что они маскируют свое поведение), поэтому выигрывает как обычно — казино.


    1. Paskin
      08.09.2021 08:09

      Есть сайты вроде Zynga - где боты не только играют, но они и напрямую интегрированы в движок. Это видно по ставкам на очень маловероятные комбинации с выпадением этих самых комбинаций - или "знанию" ваших карт "соперниками".


    1. F10PPY
      08.09.2021 12:58

      Каким образом они маскируют поведение? Есть статистика, она одинаково собирается на ботов и не ботов. Понятно что хороший бот будет делать случайные отклонения и менять стиль игры, но так же делают и более-менее хорошие игроки начиная со средних лимитов. Можно неделю играть пассивно, а потом неделю агрессивно, а статистика при этом будет средней, вот и маскировка. При этом надо понимать, какое представление о вас в данный момент имеет соперник. Были стратегии , по которым можно было играть в хороший плюс без какого-либо учёта статистики соперника, а свои действия выполнять буквально по бумажке, например стратегия коротких стеков, я по ней играл и бота сделал по ней, но правда забанили и я бросил эту затею в итоге. Казино то понятно что выигрывает, но и боты значит тоже, раз их полно, как вы говорите. Кстати в hyper sng турнирах, например, действия и статистика соперника почти не важны, там основа это ICM, и бота как раз очень просто сделать, но прибыль там в любом случае очень низкая, и брать их можно только огромным количеством.


  1. lxsmkv
    04.09.2021 14:27
    +1

    в принципе, реализация программы выигрывающей в покер [..] упирается в наличие достоверной статистики прошедших игр
    Я, видимо, что-то не так понял.
    Разве у этого эксперимента есть память? Единственное, что можно увидеть на большой выборке это регулярности в генераторе псевдослучайных чисел. А так, все игровые сессии «одинаковые».

    … Аааа, вот, простите, почитал комментарии, и понял, вы имеете ввиду использовать сбор и анализ данных, чтобы делать обоснованные предположения о стратегиях игроков. Окей. Да. Так в любом киберспорте уже довольно давно делается. Наверно в покере даже эти стратегии лучше «видно», ведь там люди часто придерживаются какой-то личной псевдорациональной стратегической линии.


  1. thecove
    04.09.2021 14:45
    +2

    Поставленная задача была решена лет 5 назад ( могу и приврать ибо гуглить лень ) парнями из MTI. Обученная ими нейронка уверенно обыгрывала топовых игроков.

    Обещали выложить в паблик код но вроде так и не выложили.

    А теперь покритикую так как в этой теме уже много лет.

    Колода это выборка с изъятием, из них при начальном раскладе известны 5 карт - 3 на столе и 2 на руках, 

    уже ошибка. Вначале раздается по 2 карты игрокам это префлоп. Уже на префлопе можно коллировать или повышать или пасовать. Пара двоек на префлопе - это почти приговор. Надо сбрасывать особенно если противники повышают и вы не на блайнде сидите. Пара тузов - надо блефовать и давить ставками или сбрасывать тут что чуйка говорит. Хотя откуда у машины чуйка?

    Получилось, что для любого начального расклада можно посчитать некую абстрактную вероятность. 

    неа. Ничего это не означает - сферический конь в вакууме. На любом раунде начиная с префлопа до ривера важна не вероятность выигрыша а обмануть соперника внушив ему что ваша карта лучше его. Покер лишь на 50% это теорвер. Остальные 50 это психология и блеф.

    Практической пользы от вашей работы вы уж простите ноль целых ноль десятых.

    Копайте в сторону нейронки.


    1. tmnhy
      04.09.2021 15:43
      +1

      Покер лишь на 50% это теорвер. Остальные 50 это психология и блеф

      Это вы сейчас ситуацию для хедз-апа или для вечерней дружеской катки обрисовали. Или для финала турнира.

      Но современный «профессиональный» покер — это два десятка одновременно открытых столов плюс 100% математики плюс SharkScope. Здесь нет места психологии и тем более блефу.


      1. thecove
        05.09.2021 14:23

        я не играю в онлайне и никогда не играл. Только за столами с живыми игроками и в казино и в дружеской катке.


        1. tmnhy
          05.09.2021 16:51

          Только за столами с живыми игроками и в казино и в дружеской катке.


          В России IRL с покером не всё так просто. С онлайновым тоже, но попроще.


        1. AstraVlad
          06.09.2021 09:40

          Есть у меня знакомый, который профессионально играет в покер, для заработка, так он играет именно так, как пишет tmnhy: аккуратно и на чистом расчете. Говорит: "мне нужно каждый день кушать, а не банк сорвать".


    1. dimaal
      08.09.2021 12:58

      Оптимистично - не имея понятия об игре, разрабатывать программу для игры неё. Для примера:

      Пара тузов префлоп это сильнейшая комбинация карт. С парой тузов префлоп не блефуют (блефуют со слабой картой). Имея пару тузов префлоп - цель игрока получить уже на стадии префлоп торговли как можно больше денег в банк и выбить максимальное количество игроков из игры (идеально остаться 1 на 1) постфлоп. Имея пару двоек в руке это никакой тне приговор - т.к. в 12% случаев вы получите на флоре сет и имея не опасный флоп (типа 289) можно выиграть много денег у той же пары тузов. Поэтому имея пару двоек префлоп - цель как можно дешевле увидеть флоп, а затем пасануть при невыходе третей двойки.

      Это только крупица того, что нужно знать пытаясь играть в покер (или разрабатывать программу для покера). Кроме того, для успешной игры нужно принимать во внимание глубину стека противников, их типовые стратегии и текущее психологическое состояние.


  1. zoldaten
    04.09.2021 17:16

    Интересное начало. Но мир не стоит на месте, и кроме поиска по дереву есть и другие алгоритмы.
    «ГЛУБОКОЕ ОБУЧЕНИЕ И ИГРА В ГО» почитайте. Отличная книга, жаль только не все опыты можно повторить для простого смертного.


  1. kulikovDenis
    05.09.2021 17:57

    Ассистенты игры в онлайн покер, находятся в полулегальном положение, они пользуется спросом и за них готовы платить деньги. Их задача обычно не играть заместо игрока, а подсказывать текущий расклад, помнить какие карты ушли, и какова вероятность успеха/не удачи при следующих шагах. В принципе теоретически ничего не мешает построить марковскую сеть и принимать решение за игрока, но как ни странно спросом пользуется именно ассистенты, а не боты. Ботов конечно же отлавливают, и блокируют, но это другая сторона проблемы, не алгоритмическая. Хотя она тоже алгоритмическая, но с другой стороны.


    1. victor79 Автор
      05.09.2021 18:15

      Ассистенты игры в онлайн покер, находятся в полулегальном положение

      А почему полулегальность? В чем здесь какое-либо мошеничество?

      Страховщики и банки очень даже пользуются софтом оценки рисков, суть которых та же, что и ассистента игры в онлайн покер.

      Вот если я к примеру буду записывать ходы на бумажку, это легально.
      Если я буду их сохранять в эксель и после считать статистику, это легально?
      А если я так же буду сохрать, но в базу данных?
      А если статистика предоставлена порталом онлайн игры для всех желающих?
      А если я из этой базы данных подтягиваю ответ во время онлайн игры?

      Так же само слово полулегальность напоминает слово полубеременность.


      1. JINR
        05.09.2021 19:25

        Игра в покерном клиенте (как и в любом другом сервисе, игре) не предполагает, что вы будете пользоваться дополнительным софтом, т.к. клиент игры считается производителем самодостаточным. Использование любых ассистентов во время игры даёт необоснованное преимущество, и это карается.

        "Полулегальность" состоит в том, что есть списки запрещённого софта. Но есть софт который даёт некое преимущество, но пока не забанен, т.к. у него есть отмазка в виде того, что его можно использовать не во время игры (хотя имеется функционал для подсказок в игре). Но в случае каких-то спорных моментов клиент игры это отследит и казино решит вопрос в свою пользу.


        1. gremlin244
          06.09.2021 00:13

          Ни один нормальный рум не запрещает использовать, например, Holdem Manager, который предоставляет в том числе hud с отображением статистики. Им пользуются примерно все сколько-то серьезные игроки, включая амбасадоров брендов. Это к вопросу о том что никто не предполагает что вы будете пользоваться дополнительным софтом. Этот дополнительный, вполне легальный, софт вообще отдельная тема. Там настолько все серьезно, что автор на этом фоне написал грубо говоря «Hello world» и радуется.
          Далее, я конечно не настоящий покерный профессионал, и не искал, но как-то пока крутился в том районе, не слышал чтобы был какой-то ультимативный софт который подсказывает мувы так, что можно стабильно обыгрывать живых людей. Сговоры между людьми? Да, наверняка лобби хайстек хедз-апов до сих пор забито участниками сговоров. Торговля статистикой? Да. Волшебный софт про всех победить? Извините, нет. Единственное что в голову приходит на тему прям запрещенного софта, это всякие скрипты с отслеживанием столов с фишами, и автоматическая подсадка за них.


          1. JINR
            06.09.2021 09:01

            Фраза о том, что рум не предполагает, что вы будете пользоваться дополнительным софтом означает, что клиент самодостаточен, и для игры дополнительно ничего не нужно.
            Я соглашусь с вами в том, что вы просто мало искали. Набирайте в поиске подсказчики для покера или GTO солверы.


            1. gremlin244
              09.09.2021 02:33

              Есть мнение, что игра по тому что солвер выдает за GTO может и в минус привести уже на средних лимитах.


              1. JINR
                09.09.2021 08:57

                Солвер имеет смысл, как я понимаю, против "оптимальных" игроков, чтобы перемалывать рейк и против предсказуемых. Наверняка заходит в Zoom и SNG с коротким стеком. В кэше, да ещё и на невысоких лимитах, выгоднее просто эксплуатировать ошибки игроков.


        1. AnatolV
          08.09.2021 12:59

          а если это мной разработанный софт и не входит ни в какие списки, это легально?

          тогда имея исходники нелегального софта и чуть поправив их получаю вполне легальный софт


          1. JINR
            08.09.2021 21:28

            Пока вас не поймают за игрой с ним. Тут же расклад какой? Исходников хорошего софта вам не получить по очевидным причинам. Когда вы напишите свой, то встанет вопрос: как его монетизировать, т.к. вы потратили очень много времени и сил на его написание? Можно начать продавать софт, тогда рум отследит появление нового софта и забанит софт и игроков, которые начнут им пользоваться. Если вы будете играть самостоятельно, то это будет иметь смысл на высоких лимитах. А там вас начнут "вычислять" регуляры, которые очень не любят читеров. Внезапно появившийся игрок с хорошей игрой всегда вызывает интерес.

            Если читать покерные новости, то регулярно разоблачают то там, то тут, банят пачками. Румы в любой мутной ситуации включают презумпцию виновности. Но не всегда они очень бдительны. Бывает, что отлавливают игроков, которые успевают прилично обогатиться до момента расплаты.


      1. tmnhy
        06.09.2021 17:02

        > В чем здесь какое-либо мошеничество?

        Дело в том, что в общем и целом никто не играет против рума. Поэтому мошенничество есть, но оно не связано с асисстентами, а как и везде связано с людьми.

        Вы такой термин слышали, как «читерство»? Использование асисстента подразумевает получение преимущества перед другими игроками. Почему румы это пресекают, хотя вроде всё легально? Потому что абстрактная деятельность покер-рума состоит в организации игр и контроле за соблюдением правил и «честной» игры. И за это покер-рум с каждого выигрыша берёт процент комиссии — рейк. Основной клиент для покер-рума — это фиш, которого очень сложно будет удержать, если его будут катать «профи» с асисстентами.
        Тут, всё как и в других онлайн-играх, дашь волю читакам — потеряешь аудиторию.

        Кстати, почему деятельность в кавычках и «абстрактная», потому что румы рано или поздно, вводя новые форматы игр, по сути становятся казино, зарабатывая не только на рейке.


  1. TheShock
    06.09.2021 01:33

    Если сделать такую генерацию хотя бы 1000 раз, то думаю средняя вероятность выигрыша будет достаточно достоверна. Для современного рядового десктопа это займет ничтожные доли секунды.

    У каждого из противников всего две карты, а значит может быть только одна из приблизительно 2500 комбинаций карт. Сравниваем каждую из этих комбинаций с нашей, определяем процент более сильных комбинаций под текущую ситуацию - вот и точный шанс победы. И не нужно никакой случайности.

    Плюс такое решение легко мастшабируется на любое количество игроков - ведь комбинации нужно считать только один раз, сколько бы их за столом не было.


    1. victor79 Автор
      07.09.2021 09:47

      Там еще 2 случайные карты на стол. Итого около 4млн вариантов.


  1. Macbko
    06.09.2021 09:31
    +3

    В спойлере нудный текст

    Сразу оговорюсь, что я в покер не играю, и знаю его хуже чем те, кто играет свои первые партии в жизни. Но может это не так уж и важно?

    Нет, это важно, если вы хотите какую-то ценность вашей программы.
    Как я понял, у вас получилось что-то типа покерного калькулятора. Среди покерного софта это самое базовое. Вы можете посмотреть уже готовые реализации, например FlopZilla или Equilab, уверен, есть и другие, но это самые распространенные.

    Есть софт по сбору статистики на основе открытых раздач: HoldemManager, PokerTracker, Hand 2 Note и др.

    Если хотите посмотреть на реализацию тех самых деревьев действий - загуглите "poker solover", есть триалы, но они сложные для понимания даже для игроков с неким опытом.

    Этими программами пользуются для корректировок своей своей стратегии и работы над игрой, на это не панацея, хоть и игра по соловеру будет прибыльной.

    Тут нужно немного погрузиться в теорию покера: сейчас существует 2 (мне известные) прибыльные стратегии: Эксплоит (эксплуатирующая) и GTO. По первой - мы анализируем игры оппонента, ищем в ней ошибки и используем их себе во благо, по второй - мы делаем свою игру максимально не эксплуатируемой. Для надежности первой нам нужно иметь базу раздач на оппонента, чем больше база - тем больше будет вероятность правильности наших действий. Поэтому, строить какой-то выигрывающий софт лучше по GTO стратегии. Наверно глупо будет описывать тут всю покерную математику, просто скажу, что она сложнее, чем вы себе представляете в этой статье.

    ко мне с вопросом, как сделать программу, которая будет выигрывать в покер

    не совсем понятно, что хотели получить на выходе, но мне кажется, что бота для онлайн игры. Тут нужно будет анализировать конкретный покерный рум (сайт), его системы безопасности и алгоритмы поиска ботов, а они есть на всех нормальных румах. Вам нужно будет рандомизировать время принятия решений, эмулировать движение мышкой и кучу всего интересного. И с очень большой вероятностью ваш аккаунт все равно забанят, с конфискацией средств.

    Если же заказ был для офлайн покера, (типа подсказка в наушники, профессор лопух), то тут все сложнее. Не одна программа и не одна стратегия не может гарантировать выигрыш за живым столом из-за его короткой продолжительности. В мире покера очень плотно зашло понятие математической дисперсии. Кто не знает и лень гуглить, на пальцах: в близких к идеальным условиях выпадение решки или орла 50 на 50. И так и будет, на 1кк бросков мы получим ~500к на ~500к. На 1к числа близкие к 500. Но, на 10 бросков мы можем получить перекос 10 к 0. Так же в покере, в ситуации, где у оппонента 2% (округленная вероятность выпадения одной карты) а у вас 98% любой софт будет советовать вкидывать в такие банки максимум фишек. Но, у соперника все же есть вероятность победы. В общем, та самая доля везения. Ни одна стратегия не будет хорошо работать на короткое количество раздач.

    По поводу легальности в покер румах: боты под запретом везде. Калькуляторы и соловеры нельзя использовать во время игры (клиент это отслеживает). Сбор статистики сейчас разрешен на некоторых румах, например, самый крупный - PokerStars, но с оговорками для самих программ, иногда они вынуждены подстраиваться под правила румов и урезать часть функционала в апдейта. Но, в целом, тенденция запрещать любой софт уже пару лет как набирает обороты.

    Эта ниша сейчас имеет много сильных решений, занявших рынок и укрепившихся на нем. Это большие деньги (аудитория не бедная) и серьезные команды, которые хорошо понимают покерную математику и тенденции игры. При всем уважении, разработчик - одиночка без опыта игры с пет-проектом ничего не сможет предложить рынку. Если у вас научный интерес - посмотрите программы в спойлере, если вы хотите сделать крутого бота - как подсказал комментатор выше - смотрите в сторону нейронок, но, в игре его едва ли удастся использовать (повторю, это не легально, но, как поговаривают, боты водятся). Удачи!

    ps Волшебных палочек в нашей жизни практически нет, а если и есть, то стоят они дорого. Посоветуйте вашему заказчику найти покерного тренера. Неделя тренировок за $500-$1000 помогут ему уверенно обыгрывать большинство катранов ;)

    pps Я сознательно не рассматривал моральную сторону ботоводства, мы тут все же про технические реализации.

    ppps Прошу прощения за такой длинный комментарий, просто тема для меня инересная.


    1. victor79 Автор
      06.09.2021 10:35

      не совсем понятно, что хотели получить на выходе, но мне кажется, что бота для онлайн игры

      Хотели получить выигрышную программу на халяву или как минимум за очень дешево. Хотели меня обманом под это подписать. Меня это растроило, и я все что успел придумать опубликовал здесь.

      Посоветуйте вашему заказчику найти покерного тренера. Неделя тренировок за $500-$1000 помогут ему уверенно обыгрывать большинство катранов

      У этого способа есть целых два препятствия: здесь нужно работать (над собой), и здесь нужно платить. Не все могут осилить хотя бы одно.