Боты в покере что это
Принципы работы покерного бота
Внимание:
Не принимайте эту статью как руководство к действию, помните что использование ботов запрещено во всех покер-румах и влечет за собой блокировку аккаунта с изъятием всех денег на счету. В этой статье не будет готового к использованию кода, чтобы не облегчать жизнь скрипт-киддисам, мы рассмотрим основные принципы и алгоритмы работы бота. А знакомый с программированием человек, при желании, все равно сможет написать такую программу.
Существование выигрывающих покерных ботов всегда подвергалось сомнению, некоторые покер румы утверждают, что их софт вообще предотвращает возможность использования такого рода программ. Но любой знакомый с программированием человек понимает, что написать самого бота не составляет труда, а против любой защиты всегда найдется противодействие. Самая сложная (и поэтому самая главная) проблема — алгоритм принятия решений. Действительно, разработать алгоритм который будет приносить плюс не так просто, но это и не обязательно. Сейчас с большим количеством разных бонусов, рейкбека и других предложений от покер румов боту достаточно играть в ноль или слабый минус, что вполне реально для мелких лимитов.
Вообще самым первым ботом (точнее программой, играющей в покер) считается «Orac», который был разработан в начале 80-х известным покерным игроком Майком Каро, автором книги «Язык жестов». Одной из особенностей программы была возможность пользоваться тайминг-телзами — если оппонент долго думал, то его действия с большей вероятностью считались блефом, чем если он действовал быстро.
Основы работы бота
Получение информации
MSG_TABLE_SUBSCR_ACTION
MSG_TABLE_SUBSCR_DEALPLAYERCARDS
sit0
nCards=2
sit1
nCards=2
sit2
nCards=2
sit3
nCards=2
sit4
nCards=2
sit5
nCards=2
dealerPos=3
TableAnimation::dealPlayerCards
MSG_TABLE_PLAYERCARDS 000C0878
. 11c
. 11d
11с, 11d — наши карты (JcJd), а диллер на 3-м месте.
Способ с API-сообщениями достаточно прост в реализации и часто с его помощью можно получить всю необходимую информацию. Для его реализации нужно использовать внедрение DLL в процесс покерного клиента. Внедренная DLL-ка может нам пригодиться для имитации нажатия клавиш и другого вывода информации. Основной минус инжекта в том, что сложно скрыть такое воздействие на клиент, если он пытается отлавливать такие попытки. Но программа не может воспринимать все внедрения как взлом, потому что эти методы используют вполне честные программы, например всем известный «Punto Switcher».
Для внедрения DLL существует несколько способов:
1. Внедрение через реестр.
2. Использование ловушек (хуков).
3. Внедрение с помощью удаленного потока
4. Запись напрямую в память с помощью WriteProcessMemory(), подробнее можно почитать здесь.
Мы рассмотрим самый простой и удобный подход — использование ловушек. Для этого нужно использовать API-функцию SetWindowsHookEx(idHook, lpfn, hMod, dwThreadId), где
idHook — определяет тип процедуры захвата, для глобального перехвата необходимо использовать WH_CBT (для перехвата сообщений клавиатуры, например, можно использовать WH_KEYBOARD);
lpfn — указатель на процедуру перехвата, которая будет вызываться каждый раз при перехвате. В ней мы будем отлавливать нужные нам сообщения и выполнять необходимые действия;
hMod — дескриптор DLL-ки в которой содержится процедура lpfn.
dwThreadId — идентификатор потока на который устанавливается перехватчик (0 для глобального перехвата).
В нашей DLL обязательно должна быть функция установки ловушки и функция вызываемая при срабатывании этой ловушки:
LRESULT WINAPI CBTProc( int nCode, WPARAM wParam, LPARAM lParam) <
if (nCode return CallNextHookEx(g_hHook, nCode, wParam, lParam);
if (nCode == HCBT_ACTIVATE)
<
//Что-нибудь сделать при активации окна
//..
>
else if (nCode == HCBT_DESTROYWND)
<
//Что-нибудь сделать при закрытии окна
//..
>
else if (nCode == HCBT_SETFOCUS)
<
//Что-нибудь сделать при получении фокуса
//..
>
//Передаем управление следующим ловушкам в цепочке
return (CallNextHookEx(g_hook, nCode, wParam, lParam));
>
При установке глобального перехвата, DLL встраивается в каждый процесс в системе, чтобы не занимать из-за этого много памяти можно разбить процесс загрузки на две части. Сначала внедряется глобальная DLL, которая занимает минимум памяти и умеет только определять в каком процессе она загружена. Для нужного процесса она с помощью LoadLibrary() подгружает вторую DLL в которой и реализован необходимый нам функционал (чтение карт, логика и т.д.).
После перехвата мы можем отлавливать разные API-сообщения, которые посылаются клиенту. Например, при выводе в элемент Rich Edit (может использоваться для организации чата) используется сообщение EM_STREAMIN. И мы можем перехватить его для получения выводимого в чат текста, а вместе с ним и информации по раздаче. Для каждого рума элемент для вывода текста может быть индивидуален, но порядок действий такой же. Вообще для исследования передаваемых клиенту API-сообщений очень полезно использовать программу Spy++ (большинство из вас с ней знакомо, она входит в пакет Visual Studio) или аналог. С помощью Spy++ можно узнать заголовки нужных нам окон и узнать какие API-сообщения нам нужно перехватывать.
Все усложняется если клиент использует какие-то нестандартные визуальные элементы или нестандартные способы вывода в них информации. В этом случае уже нужно использовать реверс-инжиниринг и разыскивать эти данные в памяти процесса. Потому что все равно вся текстовая информация хранится где-то в памяти в виде строк, нам только нужно найти где.
Если невозможно устроить перехват (клиент блокирует такие попытки) или никак не удается отыскать необходимую нам информацию, мы можем использовать метод захвата экрана и распознавания по нему символов. Но этот способ лучше оставлять на крайний случай, потому что он более трудоемкий и требует больше ресурсов при работе. Главное его преимущество, что этот способ не сможет засечь покерный клиент. Можно вообще запускать покерного бота на другом компьютере (хотя часть отвечающая за нажатие клавиш должно быть на компьютере с клиентом, но для этой части не обязательно использовать внедрение DLL), куда передается видео с экрана компьютера с покерным клиентом. Еще можно запускать клиент под виртуальной машиной, а бота под основной ОС. Очевидные минусы подхода с захватом экрана — количество играемых столов ограничено разрешением экрана и зависимость от темы карт и стола используемых в клиенте.
Симуляция действий пользователя
При нажатии ботом кнопок и других действиях имитирующих поведение обычного игрока нам нужно достичь максимальной правдоподобности. При этом нужно использовать случайную задержку ответа бота, чтобы не делать все действия моментально после начала хода. Из статьи о ГСЧ можно узнать, что покер рум PokerStars использует движения мышью пользователя для генерации случайных чисел. При этом ничего не мешает им использовать эту информацию и для проверки пользователей (вполне вероятно что и другие покерные клиенты ведут такую «слежку» за своими игроками). Поэтому важно совершать случайные движения мыши по экрану и передвижение курсора в точку нажатия кнопок. Еще можно делать случайные клики за пределами окна покерного клиента (по рабочему столу, панели задач).
Поэтому оптимально будет работать с мышью программно напрямую. Есть вариант находить хэндл нужных кнопок и посылать им сообщение с помощью SendMessage(), но лучше минимально воздействовать на сам клиент, а делать все извне. Получается нужно найти локальные координаты кнопок в окне, для этого можно использовать все тот же Spy++. Если настроить его для отлова сообщений мыши в покерном клиенте, то при нажатии на нужную область мы получим и локальные координаты клика в окне. Примерно так:
00120644 P WM_LBUTTONDOWN fWKeys:MK_BUTTON xPos:840 yPos:103
Так можно найти координаты прямоугольника внутри кнопки, из которого случайно нужно выбирать точку для нажатия, чтобы имитировать поведение человека.
Для управления мышью будем использовать API-функцию SendInput(UINT nInputs, LPINPUT pInputs, int cbSize). Ей передается массив структур INPUT, который содержит последовательные действия с мышью и клавиатурой. Так выглядит код перемещения мыши в определенную позицию и нажатие ее левой кнопки:
//Координаты в окне клиента
POINT coords;
coords.x = 840;
coords.y = 103;
//Конвертируем в координаты экрана
ClientToScreen(hWND, &coords);
//Получаем разрешение экрана
HDC hdc = GetDC(NULL);
int screenWidth = GetDeviceCaps(hdc, HORZRES);
int screenHeight= GetDeviceCaps(hdc, VERTRES);
ReleaseDC(NULL, hdc);
//Конвертируем координаты в глобальные
double worldCoords = 65535 * coords.x;
double buttonX = worldCoords / screenWidth;
worldCoords = 65535 * coords.y;
double buttonY = worldCoords / screenHeight;
// Создаем массив структур INPUT
INPUT input[3];
MOUSEINPUT mouseInput;
// Двигаем мышь к кнопке
input[0].type=INPUT_MOUSE;
mouseInput.dx = ( int )buttonX;
mouseInput.dy = ( int )buttonY;
mouseInput.mouseData = NULL;
mouseInput.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
mouseInput.time = 0; //Здесь можно использовать случайное время 1-2с.
mouseInput.dwExtraInfo = 1001;
input[0].mi = mouseInput;
// Нажимаем левую кнопку мыши
input[1].type=INPUT_MOUSE;
mouseInput.dx = ( int )buttonX;
mouseInput.dy = ( int )buttonY;
mouseInput.mouseData = NULL;
mouseInput.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE;
mouseInput.time = 0; //Здесь можно использовать случайное время 1-2с.
mouseInput.dwExtraInfo = 1001;
input[1].mi = mouseInput;
// И отжимаем.
input[2].type=INPUT_MOUSE;
mouseInput.dx = ( int )buttonX;
mouseInput.dy = ( int )buttonY;
mouseInput.mouseData = NULL;
mouseInput.dwFlags = MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE;
mouseInput.time = 0; //Здесь можно использовать случайное время 1-2с.
mouseInput.dwExtraInfo = 1001;
input[2].mi = mouseInput;
int numberOfInputs = 2;
// Посылаем наш INPUT
SendInput(numberOfInputs, input, sizeof (INPUT));
Эту функцию можно использовать не только для любого перемещения и нажатия кнопок, но и для работы с клавиатурой. Для этого нужно передавать аналогичную структуру KEYBDINPUT, хотя использование клавиатуры чаще всего нам не понадобится.
Здесь мы разобрали ввод и вывод информации, которые являются основой для всех программных действий бота. В следующей части мы разберем модуль принятия решений – основу логики бота, рассмотрим разные стратегии, которые можно применить для нашей программы.
Насколько опасен искусственный интеллект в покере: разбираем успехи Cepheus, Libratus и Pluribus
За последние двадцать лет искусственный интеллект (ИИ) сделал огромный рывок вперед. Ни один человек уже не способен тягаться с машиной в шахматы. Но покер отличается от шахмат. Если в шахматах ситуация на доске как на ладони, то в покере неизвестно, какие карты у соперника на руках.
Создание ИИ, который смог бы решать задачи, не обладая полнотой данных, стало для ученых настоящим крестовым походом.
Эволюция покерных программ
Первая покерная программа появилась в 1984 году на WSOP. Уже тогда она учитывала скорость принятия решений человеком. И если оппонент размышлял слишком долго, программа склонялась к тому, что он блефует. Стоит ли говорить, что сильные игроки сразу подметили эту особенность и нещадно ее эксплуатировали.
В 1997 году группа ученых из университета Альберты разработала покерного бота Loki. Сперва планировалось создать программу для игры на 9-макс столах, но в ходе тестов ученые осознали, что на тот момент это невозможно. Loki переделали под формат хедз-ап. Но бот все равно сильно уступал профессиональным игрокам.
Первый настоящий прорыв произошел в 2015 году, когда в университете Альберты представили покерного бота Cepheus, заточенного для игры в лимитный Холдем. Математически бот играл практически безупречно, поэтому с легкостью обыгрывал людей, которые допускали ошибки.
Стример тестирует бота Cepheus на сайте университета Альберты
Libratus: первая победа ИИ против профессионалов
Несмотря на поражение, ученые из Карнеги-Меллона сдаваться не собирались. Долгие месяцы они бились над тем, чтобы доработать свою программу. Новая версия вышла в январе 2017 года и получила название Libratus.
Ученые изменили подход бота к игре. Если раньше покерные программы группировали схожие ситуации по ряду признаков, что снижало требования к ресурсам, Libratus рассматривал каждую руку, как уникальную. И выстраивал собственные стратегии.
Топовый рег Даг Полк против ИИ
Большое значение в игре бота имела рандомизация действий и вариативность ставок. Он часто пользовался крупными овербетами, и оппонентам было трудно понять — блефует машина или разыгрывает так премиум руки. Бот ставил огромные ставки в обеих случаях.
Самая спорная раздача в этом матче:
Префлоп: МакАулей — префлоп рейз в позиции, Libratus — 3-бет с 53s, МакАулей — 4-бет, и машина сделала колл. Это уже является странным решением — большинство игроков выкинут такую слабую руку на 4-бет, тем более без позиции.
Флоп: KQJ, две червы. У МакАулея флеш-дро. Оба соперника — чек.
Терн: пришла еще одна черва. Даниэль снова прочекал вслед за ботом, пытаясь скрыть силу своей руки.
Ривер: пришла пятерка. Бот сделал ставку, получил минрейз и… пошел в олл-ин. Даниэль сделал легкий кол с флешем и выиграл эту раздачу.
Работа Libratus требовала значительных мощностей. Все расчеты проводились в Питтсбургском центре суперкомпьютеров на машине с 274 Терабайтами оперативной памяти и мощностью в десятки тысяч раз превышающей домашний ПК.
С игрой один на один ИИ справился, но наличие за столом дополнительных игроков увеличивало сложность вычислений в разы. Поэтому многие скептически отнеслись к заявлениям, что Libratus способен побить 6-макс. Доказать, что скептики не правы, вызвались Туомас Сандхольм из лаборатории Facebook и его коллега Ноам Браун.
Новый ИИ: от фиша до топ-рега 6-макс за 20 часов
Если предыдущий бот изменил подход к игре, программа Pluribus, созданная двумя учеными, изменила подход к обучению. В нее больше не закладывали никаких алгоритмов и стратегий, только базовые правила покера. Затем бот начинал раз за разом играть против собственных копий, быстро усваивая ошибки и выделяя решения, которые приводили к выигрышу.
Туомас Сандхольм и Ноам Браун — создатели Pluribus
Такой подход уже использовался ранее. Именно так работали ИИ от подразделения Google DeepMind. Программа AlphaGo, основанная на принципе самообучения, в пух и прах разгромила чемпиона мира по игре Го, а ее шахматный собрат AlphaZero с легкостью расправился с гроссмейстерами и сильнейшими шахматными программами, основанными на заложенных алгоритмах.
Самообучаемый ИИ прогрессировал с невероятной скоростью. Чтобы достичь уровня среднего покерного игрока, Pluribus понадобилось семь часов. Через 20 часов он играл уже на уровне топ-рега. А через 60 — практически не допускал ошибок.
Проверить, так ли хорош новый покерный ИИ, пригласили 15 профессионалов, у каждого из которых за плечами были семизначные выигрыши. Возглавлял команду Линус “LLinusLLove” Лелигер, которого многие считают лучшим на сегодняшний день кэш-игроком NLH 6-макс.
Пятеро на одного: противостояние в 6-max
Соревнование проходило в два этапа. Сначала за 6-макс столом пятеро про-игроков играли против Pluribus. Затем пять копий бота играли против человека. И в начале каждой раздачи у всех участников было по 100 bb.
Pluribus сразу же поставил в тупик профессионалов нестандартными решениями. Например, он часто делал донк-беты в ситуациях, где это считается убыточным, постоянно варьировал бет-сайзинги и ставил овербеты, которые превышали банк в несколько раз. Все профи отметили, что ИИ очень хорошо менял стратегию и почти никогда не действовал по шаблону.
Нестандартный овербет олл-ин от Pluribus
После матча у игроков спросили, каково им было играть против самого продвинутого покерного бота. Все они согласились, что Pluribus оказался очень сильным соперником.
«Чрезвычайно сложно положить его на какую-то руку. Он очень хорош в тонких велью-бетах и извлекает по максимуму велью из своих сильных рук», — Крис Фергюсон.
«В игре против бота я постоянно находил что-то новое, что хотел внедрить в свою игру. Мы, люди, стараемся упростить для себя покер. Выбираем стратегии, которые нам понятнее и проще запомнить. Но ИИ не ищет легких путей. У него сложные, сбалансированные стратегии в каждой раздаче», — Джимми Чоу.
«Самым интересным в игре против Pluribus было пытаться подстроиться под его сложные префлоп-стратегии. Бот постоянно варьирует размеры префлоп-рейзов. Что очень непривычно, если сравнивать с игрой против живых соперников», — Сэт Девис.
«Pluribus блефует намного лучше большинства регов. Он просто мастер в этом. Вот что делает игру против него такой сложной. Бот постоянно оказывает на тебя давление, агрессивно ставит, и ты понимаешь — в любой из таких ситуаций он может блефовать», — Джейсон Лес.
Реакция покерного мира на победу ИИ оказалась неоднозначной. Некоторых удивил странный выбор соперников для бота. Большинство участников были турнирными игроками, а не специалистами в 6-макс кэш. Также результат был опубликован без учета рейка. Если добавить стандартный для румов рейк, Pluribus, в лучшем случае, сыграл в ноль.
Многие выразили тревогу, что боты, подобные Pluribus, теперь заполонят столы покер-румов и онлайн-покеру наступит конец. Ведь если бот переигрывает топовых профи, что против него могут противопоставить рекреационные игроки? Им и так проблем хватает играть с теми, кто пользуется программами-подсказчиками.
Впрочем, в покере для Pluribus тоже может найтись применение… для борьбы с другими ботами. Если ИИ научился определять диапазоны рук оппонентов, вероятно, подобный алгоритм смог бы так же эффективно отличать машину от живого игрока.
Покер-боты на PokerStars
Игра ботов в покер-румах — эта тема уже давно вызывает массу дискуссий. Не обошли стороной такие обсуждения и PokerStars. Попытаемся разобраться в ситуации, в центре которой те самые покер-боты.
Покерный бот — что это?
Покер-бот — это программа, которая разработана с целью играть и выигрывать без непосредственного участия в процессе человека. Возникло это явление уже давно, практически сразу же как только появился онлайн-покер. Понятно, что покер-бот — софт по сути мошеннический, поэтому и находится в списке запрещенных сторонних программ PokerStars .
Покер-боты и PokerStars
Запрещенный софт
Боты играют в интересах PokerStars?
Играют ли боты за игроков?
Что делать в этой ситуации игрокам? Не мириться с нечестной игрой, в результате которой они теряют деньги, а информировать о присутствии покер-ботов службу безопасности PokerStars.
Чтобы не проигрывать деньги «машине», при первом же подозрении постарайтесь распознать, с покер-ботом вы играете или с живым человеком. Самый простой способ для этого — разговор, на который покер-боты точно не заточены. Попробуйте пообщаться со своим соперником в чате на те или иные темы. В случае, если последует ответ — все нормально.
Но никто не застрахован от того, что нарвется не на покер-бот, а на живого человека, который по тем или иным причинам просто не хочет общаться. Тогда, если подозрения действительно серьезные, можно попытаться помониторить оппонента. Показателем покер-бота можно считать то, что этот цифровой оппонент будет одновременно участвовать в раздачах даже не на нескольких, а на большом количестве столов. При этом будет демонстрировать поразительно одинаковые статистические показатели. Другая характерная «человеческая» черта, отсутствующая у ботов, игра в тильте. Согласны, ей подвержены и не все люди, но все же попробовать стоит.
И еще, как правило, покер-боты не играют на высоких лимитах, есть мнение, что их практически нет за кэш-столами и в безлимите. Учтите и это.
Стоит ли скачать или купить бот? Нет! Вот почему:
Безвозмездные покер-боты, которые можно скачать за символическую цену, представляют собой даже не программы, а вирусы. Нужен ли вам на вашем ПК вирус, замаскированный под покер-бот, который еще к тому же может быть заточен на передачу данных? Уверены, что нет. Если вы другого мнения, кликайте «Скачать».
Написание покерного бота
Внимание материал носит чисто ознакомительный характер, и автор не несет ответственности за закрытие аккаунтов покерными румами. По законам стран создание и использование ботов не запрещено, однако по правилам покерных румов они запрещены.
В данной статье полных исходных кодов не будет, только теоретически что и как можно использовать, и некоторые куски функций. Если ты интересуешься этим, тебе не составит собрать все в единую картину и написать свое. Так же не буду учить стратегиям игры, про термины или стратегии а так же правила можно в интернете найти много информации.
Немного истории.
Начал играть около 5 лет назад, за это время отыграно более 1 миллиона рук. В основном это No Limit Holdem (нелимитированный холдем) за короткими столами (от 2 до 6 человек за столом), есть опыт игры в Омаху, HU NL Holdem. Игра вроде как хобби и отдых. И вот как то с друзьями появилась идея написать бота, первая идея была написать под лимит холдем, и когда наполовину бот был написан, приняли закон запрещающий играть американцам в покер, в итоге с лимитом закинули бота. Первая версия была написано на нейронной сети с распознаванием образов, что это значит – обучили бота распознавать по снимкам с экрана карты, но это сами понимаете неточный метод, но при достаточно хорошем обучении распознавал с точностью 98-99%.Далее версии ботов уже работали на прямую с окнами румов, используя их ресурсы., а так же в тандеме с программами для анализа и сбора статистики игры.
Покер румы не спят.
Практически во всех покер румах есть та или иная защита и система обнаружения покерных ботов. Рассмотрим часть из них. Долгая игра – когда человек слишком долго играет, становится подозрительным, поэтому в некоторых румах могут появляться окошки с вопросами. Как защита не делать долгих сессий игры. Действия за столом – нажатие кнопок, выбор окон, действий не должно происходить не передвигая мышь, в свернутом окне. Траектории мыши лучше задать немного нелинейно, нажатия в разные места кнопок, скорость движения тоже не моментальная. Сканы запущенных процессов и скриншоты экрана – защита как говорил выше, не играть в свернутых окнах, процесс бота называть не покер-бот, и тому подобное, не оставлять окно бота развернутым на экране, имя процесса менять спустя какое то время (например через х минут перезапустить бота с новым именем процесса).
Схема покер бота.
Схему можно разделить на 3 части:
Блок 1 — блок взаимодействия с клиентом для игры в покер.
Блок 2 — блок принятия решения.
Блок 3 — блок сбора статистики, на мой взгляд лучше использовать сторонний софт, например PokerTracker3, отключив при этом вывод статистики на экран.
Далее рассмотрим каждый блок более подробно.
Блок 1 — блок взаимодействия с клиентом для игры в покер.
Этот блок служит для сбора информации на игровом столе и передачи в блок принятия решения, а так же получив ответ с решением выполнить то или иное действие как Fold, Raise, Call или All-In. Теперь рассмотрим этот блок. Часть этой части это взаимодействие с главным окном программы, это такие действия как выбор лимита, выбор стола за которым будем играть, это тоже большая часть, но на ней не будем останавливаться. Рассмотрим более подробно часть уже со столом. Сначала нам нужно найти хэндлы всех игровых открытых столов (окон), можно это сделать при помощи функции EnumWindows.
Функция EnumWindows перечисляет все окна верхнего уровня на экране, передавая дескриптор каждого окна, в свою очередь, в определяемую программой функцию повторного вызова. EnumWindows действует до тех пор, пока последнее окно верхнего уровня не будет перечислено, или пока функция повторного вызова не возвратит значение ЛОЖЬ (FALSE).
Параметры:
lpEnumFunc — указывает на определяемую программой функцию повторного вызова. Для получения дополнительной информации, см. функцию повторного вызова EnumWindowsProc.
lParam — устанавливает 32-разрядное, определяемое программой значение, которое будет передано в функцию повторного вызова.
Возвращаемые значения: если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение — ноль.
Если функция отработала успешно, мы можем получить имя окна GetWindowText, и проанализировав его понять нужное или нет окно, обычно в заголовке окна присутствует ваш ник, название покер рума и лимит. Далее не мешало бы хэндлы всех найденных окон сохранить, для дальнейшего использования, без повторного поиска, поиск нужно будет делать лишь в случае открытия нового окна.
Теперь когда мы имеем хэндл игрового окна мы можем вытягивать информацию о столе. Большая часть информации хранится в дилерском окне. Из него мы можем узнать все участников за столом, кто зашел, кто вышел со стола, кто сделал какое действие, карты на столе и свои карты. Для этого нам понадобится парсер текста, как его писать рассказывать не буду, это отдельная тема, главное что идея ясна J. Но перед парсером нам нужно сначала найти элементы окна, и среди них найти дилерское окошко. Очень часто дилерское окно это класс производный от Internet Explorer_Server, чтобы его найти воспользуемся функцией EnumChildWindows, а затем GetClassName.
EnumChildWindows перечисляет дочерние окна, которые принадлежат определенному родительскому окну, в свою очередь, передавая дескриптор каждого дочернего окна в функцию повторного вызова, определяемую программой. Функция EnumChildWindows работает до тех пор, пока не будет перечислено последнее дочернее окно или функция повторного вызова не возвратит значение ЛОЖЬ (FALSE).
Параметры:
hWndParent — идентифицирует родительское окно, чьи дочерние окна должны перечисляться.
lpEnumFunc — указывает на определяемую программой функцию повторного вызова. Для получения дополнительной информации относительно функции повторного вызова, см. функцию повторного вызова EnumChildProc.
lParam — устанавливает 32-разрядное, определяемое программой значение, которое будет передано в функцию повторного вызова.
Возвращаемые значения: если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение — ноль.
Теперь можно приступать и к парсингу текста. Наш ход или нет можно анализировать исходя из того какие кнопки доступны нам в данный момент. Это можно сделать как через ресурсы так и и просто по точкам на экране в этом окне. Далее если наш ход то передаем известные данные в блок принятия решения. При получении ответа делаем соответствующее действие. В этой части еще не рассмотрено как нажимать на кнопки, но это думаю и сами осилите.
Блок 2 — блок принятия решения
Этот блок, сердце всего бота, т.к. от него зависит насколько он успешен в игре, насколько правильные принимает решения. В журнале Хакер 137 от 06.2010 рассматривался пример полностью опирающийся на теорию вероятности и это хорошо, но чтобы получить достаточно достоверный результат надо провести достаточно много итераций. Чтобы играть достаточно уверенно против противника мы должны знать его диапазон и как он играет(это кусок привязан к статистике), так же есть определенные стратегии игры, зависящие от количества денег у вас, от количества игроков за столом, и самой стратегии игры. От всего этого зависит стартовый диапазон рук, и действия на последующих улицах, например человек играющий по стратегии коротких стеков (SSS) редко делает какие то ходы на ривере (когда выложена 5 карта на стол), т.к. к этому моменту он часто уже в Аллине (пошел в ва-банк). Оценка ситуаций так же идет в подсчете аутов, ауты это количество карт, которое улучшит наше положение на последующих улицах, отсюда вытекаю такие комбинации как стрит дро, стрит в дырку, флэшь дро и т.д. Дро это тоже комбинация и в зависимости от количества аутов имеет цену.И имея определенную комбинацию, даже в данный момент не победную, мы уже строим линию игры. Благодаря этим дополнительным данным мы уже можем принимать решения в зависимости от выбранной стратегии, если добавить поверх еще статистику игрока они будут еще точнее, а при добавлении полного просчета эту выборку еще можно дополнить. Надеюсь донес свою мысль о сокращении выборок и принятия решений, все это складывается на личном опыте игры и принятия решения, т.к. в несколько предложений не расскажешь теории игры в покер, которая издается во многих томах, о разных ситуациях, который бесчисленное множество, хотя можно и выделить по основным группам…
Сначала нам надо узнать ситуацию на столе, и узнать какая комбинация у нас имеется. Вот пример кода определения комбинации(переписал более понятно, но может не оптимально):
В итоге в соответствующих переменных мы имеем данные о текущем положении дел. При чем заметьте понятия как фул хауз нету, это производная из пара и трипс или сет. Тут еще нужен кусок который определяет готовность руки, т.е. готовая, не готовая, полуготовая. Например такой код:
Исходя из этих данных идем к части, которая получает статистику об оппонентах, расчеты о шансах банка и другие необходимые, принимаем решение о действии и переходим к первому блоку – выполнить действие.
Блок 3 — блок сбора статистики
Это немаловажный блок, помогающий в принятии решений, вы можете как сами собирать статистику, как воспользоваться сторонними программами. Я опишу пример запроса к PokerTracker3, программа для сбора и анализа статистики игры, параметров в программе более 100, но нам хотя бы для примера достаточно и нескольких основных. В PokerTracker3 база хранится в Postges базе. Пример запроса:
На выходе получим по определенному игроку выборку, сайтов на которых такой ник имеется в базе, можно сократить по нашему сайту только, количество рук оппонента (нужна для точности показаний), VPIP(% рук с которыми заходит в игру), PFR (preflop raise –префлоп рейз ), ATS (attemptto steel – сколько крадет блайндов на префлопе), CBET (c-bet on flop – ставка в продолжение на флопе),BBS (big blind steel –кража большого блайнда ), SBS (small blind steel – кража малого блайнда). Эти параметры в основном используются при расширенной стратегии коротких стеков, для полных стеков этих параметров мало, но в качестве примера как их получить хватит. Для чего все эти параметры нужны и как их использовать советую почитать соответствующие ресурсы.
После того как мы получили дополнительную статистику переходим ко второму блоку и корректируем наше решение об игре.
В заключение.
На написание этой статьи подвинули статьи из журнала Хакер 137 от 06.2010 «Натягиваем сетевые poker room’ы» и Хакер 139 от 08.2010 «Симуляция покерного оргазма». Так как с автором я не полностью согласен и тему считаю полностью не раскрытой и хотелось поделиться своим мнением.