概要
筆者は自分のポーカーアプリ”Exotic Poker”をリリースした際に、HUD(Head-Up Dsiplay)の実装を難しかったため見送ったと書いたが、これから実装していく上で考慮しなければならないことを書いていこうと思う。”計算して集計するだけだろ”と思うかもしれないが、思いのほか考えなければならないことがあるということで、どのあたりが難しいかが分かるように説明できていれば良いかなと思う。また、これらのデータ設計は一度決めてしまうと(不可能ではないにしても)後戻りが難しい部分もあるので、将来的にどこまでの情報を見せたいか、あるいは、利用するつもりかということを考えたうえで決定していく必要がある。
スタッツ(統計情報)の集計単位
プレイヤーの統計情報はポーカーアプリ内でプレイできるゲームの種類や経済条件毎に分けて集計した方が良いだろう。例えば、テキサスホールデムで6maxのRing Gameしかプレイできないゲームであれば、集計単位は一つのみで良いかもしれないが、ゲームの種類がテキサスホールデムとオマハがある場合などは混ぜて集計しても意味の乏しい数値になるだろう。同様にして、テーブルの人数やポジションが変われば戦略や統計情報も変わるので分けて管理する方が良い。Ring GameかS&G,MTTかでも戦略は変ってくるだろう。
これらの集計単位となるKey情報をどう定義するかをあらかじめ定めておく必要がある。1件1件のゲームデータを保存しておいて必要なデータを毎回集計するのはパフォーマンスが悪いため、統計情報を計算するための中間テーブル(Key毎の集計値を計算するテーブル)を作成・管理しておくことでパフォーマンスを改善できる。この中間テーブルの集計単位となるKey情報を定めておくとよいだろう。筆者のゲームではこれらのゲームの条件はすべて任意で変更できるので以下のようなKey情報で分類した方が良いだろう。
- ゲームの種類: テキサスホールデム、オマハなど
- 経済条件の種類: Ring, S&G, MTTなど
- プレイヤー数: 2~12
- ポジション: BN, SB, BBなど
- スタック: -10bb, 10-20, 20-30, 30-50, 50-100, 100-など
もちろん、画面上に表示したい数値はプレイヤー数、スタックやポジションを無視した平均値である場合もあるが、この場合は該当のデータを中間テーブルから集計して計算すればよいだろう。
スタッツの種類
エムホールデムやポーカーチェイスでは対戦相手をタップするとそのプレイヤーのVPIPや勝率といったデータが表示されるが、自分のゲームアプリでどのような統計情報を表示したいかもあらかじめ定めておく必要がある。また、AIなどの行動を決定する際に対戦相手の統計情報を考慮して行動を決定するモデルやAI自身の行動パターンを統計情報から定めるなどする場合はさらに細かい統計情報が必要になるので注意が必要だろう。
ひとまず、筆者が画面に表示したい項目(スマホの画面では表示できる広さが限られるため、絞り込むと思うけど)やAIに利用させたい統計情報は以下のようなイメージである。
- プリフロップ
- ハンド数: 統計情報の信頼性を表す指標になる
- VPIP (Voluntary Put in Pot) : プリフロップで自発的にチップをポットに入れた比率
- PFR (Pre-Flop Raise): プリフロップでレイズした比率
- 3Bet: 3ベットが可能なシチュエーションで実際に3ベットした比率
- F23B: 3ベットに対してフォールドした比率
- ・・・(その他、4ベット以降のデータ)
- ポストフロップ
- Aggression Factor: ベットかレイズを選択した回数 / コールの回数
- Aggression Frequency: ベットかレイズを選択した回数 / チェック以外のアクション回数
- Continuation Bet: CBが可能なシチュエーションで実際にCBを打った比率
- Action to Continuation Bet (Fold to CB, Call to CB, Raise to CB)
- Donk Bet: DBが可能なシチュエーションで実際にDBを打った比率
- Action to Donk Bet (Fold to DB, Call to DB, Raise to DB)
- Check Raise: CRが可能なシチュエーションで実際にCRを打った比率
- Action to Check Raise (Fold to CR, Call to CR, Raise to CR)
- Stage Seen (Flop Seen, Turn Seen, River Seen)
- ショーダウン
- 勝率: チップを獲得したハンド数/ハンド数
- Win Rate: 100ゲーム当たりの平均チップ獲得数 (bb換算)
- WTSD (Went to Showdown): ショーダウンしたハンド数/フロップを見たハンド数
- W$SD (Won Money at Showdown): ショーダウンでチップを獲得したハンド数/ショーダウンしたハンド数
大分欲張りな気もするが、AIの行動を統計情報から定めるモデルみたいなのを実装する場合はこれぐらいのデータが必要になると推測される。
スタッツを計算するための基礎情報
前節で示したスタッツを計算するためには、毎ゲームごとにこれらの情報を計算するために基礎情報をログとして保存しておく必要がある。VPIP,RFP,3BetやCB,DBは一般的に分母がハンド数ではなく、それの行動ができる回数のうち、実際にその行動を選択した回数の比率として計算される。例えば、CBであれば自分がアグレッサーで、かつ、Donk Betされなかった場合にどれだけの比率でCBを売ったかの比率として計算される。これを計算するためには、アグレッサーで、かつ、Donk Betされなかった回数やその状況でベットしたかをフラグとして記録しておく必要がある。
わかりづらいのがVPIPで、これは分母がハンド数でも良いのではと思うかもしれないが、ポジションがBBで手前のプレイヤーがすべてフォールドした場合などは、ハンド数は+1であるけど、VPIPの分母は自発的にチップを投入する機会がなかったため+0としてカウントしなければならないということになる。VPIPはプリフロップでコールかレイズをした回数(VPIP_count)を自発的にチップを投入する機会の回数(VPIP_oppotunity)で割ることで計算する必要があるということになる。
Fast Foldの場合
Fast Foldの場合、自分の手番が来ていないにもかかわらずFoldすることができるが、この場合スタッツはどのように計算すればよいだろうか?一般的には、Foldした時点の状況で集計値を計算するようである。言い換えれば、Foldした時点で次が自分の手番であったものと仮定して集計値を計算するということになる。これは、通常の自分の手番まで待って行動する場合と比較して、スタッツに一定のバイアスを掛ける原因になるらしい。
Fast Foldでは、3bet%の率が通常の場合(6~8%)と比較して3%程度高め(9~11%)に観測される傾向があったり、F23B(Fold to 3Bet)も高めに観測されるようである。Fast Foldとそうでないゲームではやはりルールの違いによる戦略の差異や集計値の計測方法に伴うバイアスのために、同一のものとして比較することができないようなので注意が必要だろう。そこまでの区別は必要ないかもしれないが、念のため集計単位のKeyにFast Foldかどうかを含めておいた方が良いかもしれない。
AI(NPC)における利用
スタッツは人間が見て、対戦相手の性質を推測することに用いるが、AI(NPC)を利用したアプリにおいても、いくつかの利用方法があるだろう。例えば、以下のようなものが考えられる。
- 開発したアルゴリズムが想定しているような戦略を実行しているかの確認のためにスタッツを利用する。
- AIのアルゴリズム自体が対戦相手のスタッツを参照して、対戦相手の性質によって戦略を変えるようなアルゴリズムを採用する(AIの行動決定関数のパラメータとして用いる)。
- スタッツ(VPIP,CBなど)の情報を指定して、そのスタッツを複製するようなAIアルゴリズムを利用できるようにする。
筆者のアプリでは特に3.の利用方法が重要であるかもしれない。現状のNPCは期待効用を最大化する行動を選択するアルゴリズムにしているが、結果としてCBやDonk Betを何も考えずに打っているため、人間らしい打ち手になっていないように見える。これをスタッツを指定して、その数値に合うように行動を調整するようにすれば、より人間らしい行動になるかもしれない。これらのデータをAIモデルのパラメータとして設定して、実際に対戦してみることができる機能などがあれば面白いのではないだろうか。ひとまず、スタッツを集計・表示する機能を開発して、指定されたスタッツの通り戦略を決定するAIアルゴリズムを”Exotic Poker”に追加していこうかと考えている。
おまけ:実装した画面
文章を書き終わってから実装しようと思っていたのであるが、ほぼ同時に実装が終わってしまって、筆者が開発したポーカーアプリ”Exotic Poker”の最新バージョンではHUDが見れるようになっている。アプリの宣伝も兼ねて、画面を紹介しよう(数値はテストデータなので適当)。

あまり深く考えず計算できるものは計算したということで、通常より多めに指標が表示されている。CB(Continuation Bet)、F2CB(Fold to CB)は内部的にはStage毎にデータを持っているが、画面上はFlopのデータを表示している。AGG,AFqはポストフロップの集計値で計算している。プレイヤーの性質を測るという意味では十分であろうと推測される。
シングルプレイ(対戦相手がNPCのゲーム)ではなるべく早めに Fast Foldを導入して、自分のプレイの統計情報を確認出来たり、AI学習用のデータを高速で打ち込めるように開発を進めていこうと考えている。
