CODING== maxBet)) {continue;}if (moneyOfPlayers[curPlayer] == 0) {continue;}Схема симулятораÌåòîä äëÿ îïðåäåëåíèÿ õîäà ïîëüçîâàòåëÿpublic int getAction(float p, float totalBet, floatcurBet, float pot, int betting, int minRaise) {if (curBet == 0) {btnCall.setText("Check");} else {btnCall.setText("Call " +String.valueOf(curBet));}btnCall.setVisible(true);btnFold.setVisible(true);btnRiase.setVisible(true);btnRiase.setText("Raise " +String.valueOf(curBet + minRaise));frame.repaint();action = -1;while (action == -1) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}frame.repaint();}btnCall.setVisible(false);btnFold.setVisible(false);btnRiase.setVisible(false);frame.repaint();return action;}— номер круга торговли. Это 1 (пре-флоп), 2 (флоп), 3 (терн), 4(ривер). В начале метода проверяем на первый круг торговли,и если да, то находим позиции малого и большого блайндови кладем деньги в банк. Далее происходит сам круг торговли.Непосредственно перед ходом каждого игрока проверяются следующиепараметры: больше ли одного игрока в игре, может литекущий игрок играть. При повторном круге торговли проверяется,не равна ли ставка текущего игрока максимальной ставке (тоесть нужно ли игроку еще вкладывать деньги в банк), и есть ли уигрока вообще деньги.Проверки перед началом торговли// óâåëè÷èâàåì íîìåð òåêóùåãî èãðîêàcurPlayer = (curPlayer + 1) % 9;if (getSinglePlayer() != -1) {break;}if (stateOfPlayers[curPlayer] == false) {continue;}if ((repeatTrade == true) && (betOfPlayers[curPlayer]После этих проверок можно переходить непосредственно к определениютекущего хода игрока. Для этого вычисляем вероятность выигрышаигрока на основе его карт, карт на столе и количества игроков ивызываем метод интерфейса ILogic для определения хода игрока:Вызов методов расчета вероятности и принятия решенийfloat p=logic.getProbabilityOfWin(handOfPlayers[curPlayer], board,getActivePlayers());int action=playersList.get(curPlayer).getAction(p,totalBet[curPlayer] + betOfPlayers[curPlayer],maxBet-betOfPlayers[curPlayer],pot,betting,maxBet==0?bigBlind:maxBet);Метод расчета вероятности вызывается со следующими параметрами:текущие карты игрока, карты на столе и количество активных (тех, ктоне сбросил карты) игроков в игре.Первый параметр в методе getAction — вероятность выигрыша;второй — сумма всех поставленных денег за прошлые круги торговлии поставленных денег на текущем круге торговли; третийпараметр — то количество денег, которое нужно поставить игроку,чтобы уравнять ставки, то есть разность между максимальнойставкой на текущем круге торговли и текущей ставкой игрока;четвертый параметр — размер банка; пятый — номер круга торговли,шестой — минимальное количество денег, которое нужнопоставить при рейзе. Здесь мы приняли его как значение максимальнойставки за текущий круг торговли или, если эта ставкаравна нулю, размер большого блайнда. После получения действияот игрока (переменная action) выполняем это действие. Алгоритмтаков: если игрок сделал fold, то делаем его неактивным; еслиcall, то сначала проверяем, может ли он поставить деньги, илисразу идет all-in, а потом выполняем требуемое действие, то естьили ставим часть денег, или ставим все, что есть; если raise, тосначала уравниваем ставку игрока до максимальной ставки, апотом ставим оставшуюся часть денег, требуемую для рейза. Вобщем случае при ставке следует проверять, есть ли требуемаясумма на счету у игрока, если нет, то ставим все оставшиеся деньги(all-in). После проведения ставок всех игроков проверяем, всели игроки поставили одинаковое количество денег. Если кто-то непоставил, и у него при этом еще есть деньги, проводим повторныйкруг торговли.ÑÈÌÓËßÖÈßПеред началом игры нужно добавить игроков. Это делается следующимобразом:Добавление игроков для игры в HoldemFormList playersList=new ArrayList();playersList.add(frame);playersList.add(new FoldLogic());playersList.add(new CautiousLogic());playersList.add(new CallLogic());playersList.add(new RationalLogic());playersList.add(new AggressiveLogic());playersList.add(new CautiousLogic());playersList.add(new AggressiveLogic());playersList.add(new RaiseLogic());Во второй строчке мы добавляем в качестве игрока текущую форму, этоозначает, что все методы принятия решений для первого игрока будут110 XÀÊÅÐ 08 /139/ 10
codingÑàéòû ïî òåìåПравила покера:http://www.pokerbonus.org.ua/menu/pravila.htmlhttp://www.tehasskiy-holdem.info/http://www.pokerstars.com/ru/poker/games/texas-holdem/Фундаментальная теорема покера:http://poker-wiki.ru/poker/Ôóíäàìåíòàëüíàÿ_òåîðåìà_ïîêåðàВики по покеру:http://poker-wiki.ru/playersList.add(new RandomLogic());playersList.add(new AggressiveLogic());playersList.add(new RaiseLogic());50 раундов на моем ноуте выполнялись около 15 минут. Впринципе, приемлемое значение. Количество денег после49 раундов следующее (начальное количество у всех одинаково— $750):1-é — $5802-é — $5903-é — $5704-é — $22205-é — $5706-é — $6807-é — $08-é — $7509-é — $790INFOinfoПока в симулятореесть неточности,но если их исправитьи сделатьхороший интерфейсHoldemForm, томожно будет использоватьего длятренировки игрыв покер.вызываться из этой формы. Он, в свою очередь, будет спрашиватьпользователя, что делать — fold, call или raise.Для начала проведем игру между человеком и компьютернымиигроками, проверим работу правил симуляции— как раздаются карты, как ходят игроки, как происходитсмена дилера. Я ошибок не нашел, но они навернякатам есть. Поэтому если ты что-то нашел, или у тебя будутпредложения по улучшению программы, пиши мне наtimreset@mail.ruПеречислю некоторые неточности в симуляции, чтобызнать, где можно доделать симулятор:1) Фиксированное количество игроков. Можно сделать отдвух до десяти.2) В HoldemForm не отображается фишка дилера, хотяметод changeDillerPosition при смене дилера вызывается.Нужно добавить на форму возле игрока-дилерапометку.3) Фиксированное количество денег в начале игры. Можносделать изменение этого значения перед игрой.4) Только целые значения большого и малого блайнов.Сделать тип float для них. Int был выбран только из-запроиз водительности… и то, наверное, это спорный выбор.5) Неправильный выбор минимального значения ставкипри рейзе. Сделать вычисление минимального рейза поправилам. Ссылка на них есть в статье.6) Фиксированное увеличение ставки при рейзе. Сделатьзначение рейза динамическим — от минимального значениядо максимального.7) При открытии карт, если есть игроки с одинаковымикартами, выигрывает только первый игрок. Можно этоисправить, чтобы выигрыш делился поровну между игроками.Хотя эта ошибка будет повторяться нечасто (все-такивероятность того, что у игроков будут две одинаковые посиле комбинации, мала), лучше все же реализовать ее поправилам. После того, как был протестирован алгоритмсимуляции, запустим несколько десятков раундов в оболочкеHoldemConsole. Игроки там распределены следующимобразом:Добавление игроков для игры в HoldemConsoleplayersList.add(new RationalLogic());playersList.add(new FoldLogic());playersList.add(new CautiousLogic());playersList.add(new CallLogic());playersList.add(new CautiousLogic());playersList.add(new AggressiveLogic());XÀÊÅÐ 08 /139/ 10После второй симуляции:1-é — $5702-é — $5603-é — $5804-é — $24505-é — $5906-é — $11107-é — $08-é — $8909-é — $0ÂÛÂÎÄТеперь самое главное — интерпретация результатов.Выше можно заметить, что самый успешный игрок— CallLogic, за ним следует RaiseLogic (в первомслучае) и AggressiveLogic (во втором случае). Почемутак? Ведь самый оптимальный алгоритм у нас — этоRationalLogic и, по идее, он должен всех обыгрывать?Да, это так, но на данном этапе этот алгоритмне учитывает одной важной составляющей — историирук, то есть того, как ходят остальные игрокипри тех или иных картах и текущих ходах игроков. Аведь история рук позволяет узнать, что значат ходыигроков — блефуют ли они (то есть колируют и рейзятсо слабыми руками) или у них действительносильные карты. Больше информации об игроках, потеореме покера, приводит к лучшим ходам. Так какон это не учиты вает, а основывается только на ставкахи размере банка, то получается, что он много рукне разыгрывает, а сбрасывает. В отличие от другихигроков — CallLogic, RaiseLogic и AggressiveLogic.Они же разыгрывают большой диапазон рук, то естьблефуют. Кстати, хотел бы сделать небольшое замечаниек своей прошлой статье. В условии определениядействия вместо SB нужно использовать minRaise,где minRaise — минимальный размер ставки, которыйнужно сделать при рейзе. Он равен последней ставкеигрока, который ходил до нас. В общем, твори, дорабатывайлогику и обязательно пиши нам письма, ведьименно благодаря твоим отзывам — от критичных идаже агрессивных до позитивных и даже благодарных:) — мы приняли решение и дальше развивать темукодинга покерных ботов. Если все пойдет нормально,то в следующей статье мы реализуем взаимодействиес клиентом покер-рума — считывание информации инажимание на кнопки. zDVDdvdНа диске тебя ждутисходники. Они снабженыподробнейшейдокументациейв формате JavaDocи комментариямив коде, так что разобратьсяс ними несоставит труда. Текстпрошлой статьилежит там же.HTTP://WWWlinksМного документациипо покеру на сайтеhttp://poker-wiki.ru111