難しい!
世界で一番遊ばれているポーカーである ノーリミット・テキサスホールデムをコーディングするのが難しい。強いAI を作るのは大変なのはわかる。でもそうじゃないのだ。ルールブックを忠実にコードに落とし込むだけで難しいのだ。
ブラックジャックなんかは初心者プログラマの例題として採用できるくらい簡単だが、ホールデムを初心者プログラマの例題にだしたら泣くと思う。逆に腕に覚えがある人は実装してみるといいと思うよ。
本稿では、自分でホールデムを実装しようとする人向けに、実装上の Tips や、実装上の難所を解説したいと思う。
ざっくりとしたプログラムの構成要素
ハンド比較
ご存知のとおり、7枚から任意に5枚を選んで最大の役を作り、ほかのプレイヤーと比較する。独立性が高い部品であるし、いい腕試しにもなるので、休日にちょろっと実装してみるのも頭の体操になってよい。
駆け引きの状態遷移
大きく分けて、プリフロップ、フロップ、ターン、リバーの4つのベッティングラウンドがあるのだが、それぞれのラウンドの中で、相当複雑な状態遷移がある。チェック、フォールド、コール、レイズ、リレイズ、(リリレイズ)、オールインがあり、組み合わせは膨大になる。これらをきちんと交通整理するモジュールが必要になる。
シリアライゼーション・バリデーション・リトライ
対戦をしたり、ボット作成時に機械学習をさせるためには、プレイヤーと、ディーラー(システム)を疎結合にして、シリアライズ可能な形に実装しておくのが望ましい。プレイヤーの入力をディーラーは信用せず、各種のバリデーションを仕組んだり、無効な入力があった場合には再入力を求めたり、タイムアウトを実装するなどが必要。
はまりポイント
大体のルールをみてコーディングを始めると必ずどこかでどんづまる。はまりポイントをあらかじめ押さえておいて、データ構造の変更を最小限にしよう。
ポットとサイドポッド
誰かがオールインした後にもベットが続くとき、サイドポットという概念が出てくる。ポットをただの整数値として設計したりしてると後で泣きを見る。サイドポットは一つだけではなく、オールインする人間が複数いればサイドポットもその分だけ増える可能性がある。
ミニマムレイズ
レイズの幅にはルールがあり、リリレイズの幅にも別のルールがある。これらを考慮するために、過去のレイズ等を覚えておかなければいけない。データ構造の変更をしないようにあらかじめ設計しておく必要がある。
ポットの端数
勝者総取りのゲームではあるが、時には引き分けが発生する。端数が出てきたときにはSBの席から順に弱いものがそのあまりをもらうことになるのがわかりづらい。
アンティ・レーキ
ルールブックには書かれていないが、実際にはこれらが存在することが多く、また戦略立案にも影響する。
ボタン
基本的には、1ゲームごとに反時計回りにずれるのであるが、誰かがトンだり、離席した場合など、不規則なずれ方をする。プログラミング的には、ずれるのはBBの位置であるとしてコーディングするのがよい。ルール的にはBBが同じ人物に連続して当たってはならない
コードは?
github で細々と開発してるので興味があればどうぞ。まだ一部のルールを実装しきれていない。