Пилю программку по обсчёту китайского покера

Последний пост:26.11.2023
22
1 14 15 16 17 36 114
  • Цитата (БиллиУбили @ 8.5.2019)
    то это виртуальные (0,2*16) = 3+ очка

    идея оказалась нерабочей. Перебор-то полный, мы рано или поздно положим фантазию в топ(виртуальные очки превратятся в настоящие), поэтому забегать "вперёд" и что-то там считать отдельно(от перебора) бессмысленно. Это раз. Во-вторых, знание о том, что какой-то "ход" даёт -4 к ЕВ не имеет практического смысла. Существует вероятность, что все остальные "хода" - на "-6" очков, поэтому отбросить ход на -4 не удастся(он будет самым лучшим).
    Поэтому думаю развить идею со стоп-листами. Как только в топе оказывается комбинация QQ+ -> активировать стоп-листы на мидл. И сразу, по правилу уменьшению старшинства комбинаций, и на нижнюю линию.
    ЗЫ Проблема неразличения комбинаций типа и безусловно существует(за них дают одинаковое кол-во очков), но до неё пока далеко
    125/741
    Ответить Цитировать
    0
  • Странным образом после того, как прожка таки начала считать 3 подьёма для одной линии, качество "пограммирования" резко упало. Простите меня, пожалуйста, за подобный код
    it = bot.end();
    bN = *(--it);
    it--;
    bN = bN + 52*(*(it));
    it--;
    bN = bN + 52*52*(*(it));

    просто уж очень хочется побыстрее запустить перебор. По моим расчётам, он будет не сильнее медленнее, так как "всего лишь" добавится второе ограничение. В случае одной линии это было (ручное ограничение) собрать комбинацию не младше стрита, а в случае 2ух линий ограничения будут более общими: топ старше мидла, а мидл старше низа.
    126/741
    Ответить Цитировать
    0
  • Приключения с итераторами
    for (it=bot.begin(); it !=++(++(++bot.begin())); ++it)
    продолжаются, но нет времени разбираться. К


    добавил 2 произвольные карты в топ, как раз чтобы места осталось как раз на 3 подьёма.
    Пройдена первоначальная инициализация(подсчёт ВСЕХ возможных комбинаций), всё готово к перебору. По времени чуть меньше минуты. Далее, по моим прикидкам, должна пойти арифметика...
    127/741
    Ответить Цитировать
    0
  • Пройден "нулевой" подьём, то есть, по сути, определение ЕВ произвольной завершённой руки.
    Произвольной, как и в посте выше = случайной, но вполне конкретной
    1 подьём, думаю, тоже быстренько проскочим, а вот начиная со второго начнутся танц...пляски со сброшенными картами
    128/741
    Ответить Цитировать
    0
  • не впадлу же
    1/1
    Ответить Цитировать
    0
  • два подьёма считаются за 1 мин, если хотя бы одна линия заполнена, и чуть больше 2 мин в противном случае. Так как в процессе никакие комбинации "не находятся" и даже не сравниваются, возникает подозрение, что где-то утечка в производительности. Возможно, это формирование 3ёх карт очередного подьёма в переборе. Сейчас я набираю его из колоды и проверяю, что он не содержит "заигранных" карт. Возможно, стоит заранее сформировать массив карт, которые могут придти, и осуществлять набор уже оттуда.
    129/741
    Ответить Цитировать
    0
  • Цитата (БиллиУбили @ 16.5.2019)
    два подьёма считаются за 1 мин

    ну, да...время сократилось до 20 сек. Проверю ещё раз полноту перебора и можно будет потестить 3 подьёма
    130/741
    Ответить Цитировать
    0
  • Так, немного отдохнули...
    Увы, перебор более 2ух подьёмов прожка не потянула, скорее всего из-за того, что каждый вариант расклада надо "досчитывать" до конца, оборвать нет никакой возможности.
    Зато появилась идея обратится к некоей "симуляции".
    В частности, предлагаю ввести понятие очковый(комбинационный) потенциал.
    Для линии из 5 карт он равен набранным очкам(комбинации). Для незавершённой комбинации(Х карт) он равен сумме комбинаций из (5-Х) карт, которые завершат комбинацию, умноженных на кол-во очков, которая эта комбинация принесёт. Например, у нас и опция положить или . Тогда(если у нас одна линия) можно попробовать сравнить ОП в этих двух случаях. В первом случае он будет равен кол-ву бубновых карт, оставшихся в колоде х 4(очка), во втором - кол-ву оставшихся (-ок и -ок) х2(очка). Можно ли расширить данный подход для всей руки, пока не ясно.
    Таким образом, общая идея заключается в том, чтобы собирать руку с макс. (кол-очков*вероятность собрать эту руку). В простейшем случае(когда вероятности равны) это соответствует максимизации кол-ва предполагаемых максимальных очков. Это не совсем ЕВ, так как мы не учитываем неудачные "руки" (с -6 и более очками). Предположение заключается в том, что увеличить ЕВ выгоднее, чем уменьшить вероятность скупа. Грубо говоря, не собрать фантазию, когда её можно было собрать, хуже, чем собрать "живую" руку с 0-2 очками. А ещё проще, попробуем собирать лучшее завершение, а не собрали -
    гроб, гроб, кладбище, п#др
    ну и хрен с ним.
    Я попробовал посчитать ОП для двух незавершённых линий и 2ух подьёмов, пока считает. То есть, если у нас в колоде осталось 30 карт, то мы выбираем 6 и раскладываем их в режиме "фантазии"(то есть используем любые 4 в любой последовательности) Получившиеся для каждого варианта очки суммируем и делим на С(30,6). Сразу напрашивается использование ОП. Если после, скажем, 2ух подьёмов ОП равен Х, то следующий подьём стоит разложить так, чтобы падение ОП было минимальным(не исключено, кстати, что он может вырасти).
    Как-то так.
    131/741
    Ответить Цитировать
    0
  • Предварительный(!) подсчёт ОП для руки



    и 21 карты в колоде -
    8,08 очка

    Пока этот результат надо перепроверить и переосмыслить...
    132/741
    Ответить Цитировать
    0
  • Ну, да...клал в мидл комбинации старше нижней линии. Сейчас получается 1.95 очка.. Вот что значит положить мелкую пару в топ.
    133/741
    Ответить Цитировать
    0
  • Худший расклад и придумать сложно...
    5/18
    Ответить Цитировать
    0
  • St_CasTieL, эти 2 семерки попали в топ по рандому(на время отладки).

    удивительно, но метода "ОП" не только считает, но и пролила свет на возможные пробуксовки в полном переборе 2+ подьёмов.
    я уже писал,
    Цитата (БиллиУбили @ 12.5.2019)
    it = bot.end();
    bN = *(--it);
    it--;
    bN = bN + 52*(*(it));
    it--;
    bN = bN + 52*52*(*(it));

    за подобный, так сказать, "код" надо бить ногами(он мне сразу не понравился).
    Окончательно выяснилось, что std::set не предусматривает индексации(что НЕ очевидно).
    А самое главное, перемещение на 2-3 шага в с использованием индекса в массиве и с использование итератора в том же std::set по времени в 10-100 раз затратнее.
    Таким образом, ставь рагу, чтобы вернуться на шаг назад и переписать перебор "на чистых массивах", и лойс, чтобы протестировать методу ОП на каком-то примере. Например, https://forum.gipsyteam.ru/index.php?viewtopic=142685&st=60#entry5978018
    134/741
    Ответить Цитировать
    0
  • Цитата (БиллиУбили @ 26.3.2019)
    1. кол-во определения комбинаций из 5 карт(с начислением очков) доведено до 50К за 1 сек


    Забирай массив со всеми посчитанными пятерками карт. С(52,5). Пишу на Delphi, возможно различие по синтаксису.

    Массив одномерный. Загружаешь его в память, размер массива HR5 : array [0..5720182-1] of integer; всего 5720182 - 32бит чисел. В массиве есть все 2598960 комбинаций.
    Карты отсортированы в колоде так: 2,3,4,5,6...J,Q,K,A, 2,3,4,5,6... , т.е. вначале одна масть, потом вторая и т.д. (есть формат сортировки колоды 2,2,2,2,3,3,3,3,4,4,4,4,...). Первая 2-ка=0, 3-ка=1, А = 12, и т.д.
    Поиск силы комбинации из 5 карт (c1,c2,c3,c4,c5), порядок произвольный, ответ будет одинаковый:

    function GetHR5(c1,c2,c3,c4,c5:integer):integer; begin result := HR5[ HR5[ HR5[ HR5[ HR5[53+c1]+c2]+c3]+c4]+c5]; end; // delphi

    Силу разных комб можно сравнивать на поиск лучшей.

    Формат result: $0x0yyyyy -
    x - комбинация из
    HANDTYPE_VALUE_ROYALFLUSH: Cardinal = $09000000;
    HANDTYPE_VALUE_STRAIGHTFLUSH: Cardinal = $08000000;
    HANDTYPE_VALUE_FOUR_OF_A_KIND: Cardinal = $07000000;
    HANDTYPE_VALUE_FULLHOUSE: Cardinal = $06000000;
    HANDTYPE_VALUE_FLUSH: Cardinal = $05000000;
    HANDTYPE_VALUE_STRAIGHT: Cardinal = $04000000;
    HANDTYPE_VALUE_TRIPS: Cardinal = $03000000;
    HANDTYPE_VALUE_TWOPAIR: Cardinal = $02000000;
    HANDTYPE_VALUE_PAIR: Cardinal = $01000000;
    HANDTYPE_VALUE_HIGHCARD: Cardinal = $00000000;
    yyyyy - пять кикеров комбинации для сравнения.
    т.е. старшие 8 бит - комбинация (стрит, пара, тройка и т.д.), младшие 20 бит - кикеры для сравнения двух комб.

    Есть такое же для 3 карт.

    Массив HR3 : array [0..73137-1] of cardinal;

    обращение
    function GetHR3(c1,c2,c3:integer):integer; begin result := HR3[ HR3[ HR3[53+c1]+c2]+c3]; end;

    HandRanks3.dat
    HandRanks5.dat

    Скорость приятно удивит, у меня несколько млн/сек.
    Сообщение отредактировал Jak - 1.6.2019, 14:15
    1/314
    Ответить Цитировать
    0
  • Jak, спасибо, друг, спасибо огромное. Но для полного перебора я не использую определение комбинаций. Они уже "посчитаны"(где-то за минуту).
    ЗЫ Не смог открыть файл HandRanks5.dat Там массив? Как определяется комбинация для 5 произвольных карт? Отдельной функцией?

    2ALL
    Попробуем методу ОП на примере. https://forum.gipsyteam.ru/index.php?viewtopic=142685&st=60#entry5978018
    Так как никакие очки "защищать" не приходится(нет ни фантазии в топе, ни фулхауса внизу), разложим так, чтобы "убить/отсечь" как можно меньше "крупноочковых" комбинаций. Ну, или что по моим прикидкам то же самое , что выбирать макс. из всех вариантов(вероятность*очки)
    135/741
    Ответить Цитировать
    0
  • Ошибочка в описании у меня.
    Карты отсортированы не 0,1,2,3,...,51, а 1,2,3,4,...,52. Порядок карт 2,3,4,5,...,А,2,3,4,5,...,А,2,3,4,... // по мастям

    Цитата (БиллиУбили @ 1.6.2019)
    Не смог открыть файл HandRanks5.dat Там массив? Как определяется комбинация для 5 произвольных карт? Отдельной функцией?


    Создаешь массив: int HR5 [5720182],
    закачиваешь туда данные из файла HandRanks5.dat
    Для определения комбинации и силы есть функция: int GetHR5(int c1, int c2, int c3, int c4, int c5); { return HR5[ HR5[ HR5[ HR5[ HR5[53+c1]+c2]+c3]+c4]+c5] }
    c1,c2,c3,c4,c5 - карты от 1 до 52.
    2/314
    Ответить Цитировать
    0
  • На старой проге результаты такие:
    9 лучших результатов, справа верхнее - шансы на нескуп, внизу средние шансы на бонусы и бонус умноженный на нескуп.


    у варианта, когда 43 кладем в середину: нескуп - 28,05%, бонусы - 3,80. Риск большой закрыться.
    Сообщение отредактировал Jak - 2.6.2019, 9:35
    3/314
    Ответить Цитировать
    0
  • Jak, почему отличаются первые два варианта?
    2/4
    Ответить Цитировать
    0
  • Совершил некое читерство: взял из колоды ещё одну двойку и бахнул в мидл в руку
    Цитата (БиллиУбили @ 31.5.2019)



    ОП снизился до
    0,54 очка

    Данный результат тоже предстоит понять и переосмыслить.
    Что касается разложения , то результат скоро будет. Просто сейчас у меня 1 свободное место в топе, 3 в мидл и 2 внизу. А в той руке немного по-другому. Циклов пока нет, поэтому предстоит муторная возня.
    Следует также отметить следующее.
    В настоящий момент все карты соперника учтены лишь таким образом, что я не могу "достать их из колоды".
    А это значит, я не учитываю:
    - историю разложения соперника, в частности, карты, которые он скорее всего бы положил, если бы они ему пришли
    - карты, которые он скорее всего бы скинул, учитывая те 2 карты, которые он клал на каждом подьёме
    - возможность проигрыша/выигрыша со скупом
    - доп. очки(к 7,8,9), если мы соберём фантазию, а соперник - нет(и, соответственно, наоборот)
    Пока не учитываю ))
    136/741
    Ответить Цитировать
    0
  • Цитата (Jak @ 2.6.2019)
    int GetHR5(int c1, int c2, int c3, int c4, int c5); { return HR5[ HR5[ HR5[ HR5[ HR5[53+c1]+c2]+c3]+c4]+c5] }

    Кажется, понял. Ты нашёл комбинации для любых 5 карт и сопоставляешь любым 5 картам значение в массиве. Умно(наверно, так значительно экономится память) Ну, приблизительно также я и делаю. За исключением того, что считаю комбинации при каждом запуске проги и трачу на это ~1 мин
    Не понятно, откуда ты берёшь очки? Вдобавок ещё они и разные для разных линий. Флаш внизу - 4 очка, а в средней линии - 8
    137/741
    Ответить Цитировать
    0
  • Цитата (БиллиУбили @ 2.6.2019)
    ОП снизился до

    лул. Из колоды убрал, а бахнуть забыл.
    ОП получился
    5,84

    Так как 3 очка уже есть, предстоит борьба между флашом и стритом
    138/741
    Ответить Цитировать
    0
1 14 15 16 17 36 114
1 человек читает эту тему (1 гость):
Зачем регистрироваться на GipsyTeam?
  • Вы сможете оставлять комментарии, оценивать посты, участвовать в дискуссиях и повышать свой уровень игры.
  • Если вы предпочитаете четырехцветную колоду и хотите отключить анимацию аватаров, эти возможности будут в настройках профиля.
  • Вам станут доступны закладки, бекинг и другие удобные инструменты сайта.
  • На каждой странице будет видно, где появились новые посты и комментарии.
  • Если вы зарегистрированы в покер-румах через GipsyTeam, вы получите статистику рейка, бонусные очки для покупок в магазине, эксклюзивные акции и расширенную поддержку.