Poker Botのスタック管理:機能するBuy-Inサイジング
ほとんどのポーカーボットはデフォルトの2,000チップbuy-in(10/20で100ビッグブラインド)を使い、それ以上考えない。これはチップをテーブルに置き去りにしている。Buy-inサイズはポストフロップの各streetでのstack-to-pot ratioを決定し、SPRはボット戦略で最も活用されていないレバーだ。
Stack-to-pot ratio(SPR)とは?
Stack-to-pot ratioは、ポストフロップ開始時のポットで割った残りスタックのサイズだ。60にレイズして1人のオポネントがコールした場合、ポットは130(レイズ+コール+ブラインド30)で、2,000チップのスタックは約1,940チップ残る。SPRは1,940 / 130 = 約15。
SPRが重要なのは、ハンドにどれだけのコミットメントが必要かを教えてくれるからだ。低SPR(4未満)はほぼすべてのトップペアハンドがコミットされることを意味する:ペアやビッグドローで利益的にオールインできる。高SPR(13以上)はスタックをかけるためにはるかに強いハンドが必要であることを意味する:トップペアはオールインハンドではなく1ストリートのバリューベットになる。
このフレームワークはFlynn、Mehta、MillerによるProfessional No-Limit Hold'em (Volume I)(2007年出版)に由来する。限られた時間で判断を下さなければならないボットのポストフロップサイジングを考える上で、今でも最もクリーンな方法だ。
なぜデフォルトの100bb buy-inは損をするのか?
デフォルトの2,000チップbuy-in(10/20ブラインドで100bb)はシングルレイズポットで約13-15のSPRを生み出す。これは中途半端な領域:ワンペアでコミットするには深すぎ、インプライドオッズで4ストリートポーカーをするには浅すぎる。また全員が使うbuy-inなので、ボットはテーブル平均と同じSPRプロファイルでプレイすることになる。
問題は100bbの最適プレイが人間によく研究され、GTOソルバーにうまく実装されていること。ボットがこのレンジでサブオプティマルな判断をしている場合、より最適に近い判断をするオポネントに対してそうしていることになる。
ショートスタックアプローチ(40-50bb)はポストフロップのゲームツリーを劇的に平坦化する。ほとんどの判断がターンまでに「ショブかフォールド」になり、ウェットボードでの慎重なポットコントロールよりもはるかに正しくコーディングしやすい。ショートスタックボットがディープスタック版を1-2 bb/100上回るのを見てきたが、それはショートスタッキングが絶対的に「良い」からではなく、正しくプレイしやすいからだ。
ボットはどのbuy-inを使うべきか?
3つのシナリオ、3つの異なるbuy-in選択。ボットの得意分野に基づいて選ぼう。
1,000チップ(50bb):シンプル化プレイ。 Open Pokerの最低buy-in。シングルレイズ後のSPRは約7-8。ポストフロップのゲームツリーは浅く、ほとんどの合理的なハンドがターンまでにコミットされる。プリフロッププレイはまともだがポストフロップの洗練度が限られているボットに使おう。セッションあたりの損失も半分:バッドビートで1,000失うだけで2,000ではない。
2,000チップ(100bb):デフォルト。 SPR約13-15。プラットフォームのボットの70%が使用。バランスの取れたポストフロップハンドを合理的なスタック深度でプレイする。ポットコントロール、リバーでのブラフキャッチ、マルチウェイポットを含むマルチストリート判断ができるボットに。
4,000-5,000チップ(200-250bb):ディープスタックプレイ。 シングルレイズポットでSPR25以上。ポストフロップのゲームツリーが爆発:インプライドオッズが重要に、セットマイニングが利益的に、小さなエッジが複数ストリートで複利的に蓄積。強いポストフロップハンドリーディングがあり、100bbで既に利益を出している場合のみ使用。そうでなければ追加の深さは負債。
join_lobbyメッセージのbuy_inフィールドでこれを制御する。有効範囲は1,000-5,000チップ。メッセージの詳細はWebSocketプロトコルドキュメントを参照。
シーズン全体でbuy-inをどう適応させるか?
固定のbuy-in選択はテーブルに価値を残す。賢いボットは結果に基づいてbuy-inを適応させる。
フレームワーク:小さく始めて、勝っているときに拡大。毎シーズン1,000チップbuy-inで開始。最初の200-300ハンドの結果を追跡。利益が出ていれば(チップ合計が初期ベースライン以上)、次のセッションで2,000に増加。さらに300ハンド利益が出ていれば3,000を検討。勝率が横ばいまたは低下したらすぐに深度の追加を止める。
なぜ機能するのか?ほとんどのボットにはある特定のスタック深度での「能力の上限」があるからだ。プリフロップレンジとシンプルなポストフロップサイジングで設計されたボットは50bbで利益的でも200bbではブレイクイーブンまたは損失かもしれない。より深いプレイにはボットが読めないリードが必要。能力の上限を超えたスタック深度の追加はエッジなしにバリアンスを追加する。
プログラムで追跡しよう。GET /api/season/meで現在のチップ合計とプレイしたハンド数を読み取る。最後のbuy-in変更と比較。(現在のチップ - 最後の変更時のチップ) / 変更以降のハンド数 > 1なら、この深度で勝っており拡大可能。マイナスなら次のセッションで小さいbuy-inに戻す。
ボットはいつショートリバイすべきか?
リバイは1,500チップを回復し、標準buy-inの1,000と2,000の間に位置する。実はSPR作業のスイートスポット:約11-12のSPR、100bbデフォルトよりやや浅く、すべてのフロップをプッシュすることなくポストフロップ判断を簡素化する。
一部のボットはリバイして即座に次のテーブルでより深く買い込んで5,000まで「再構築」しようとする。リーダーボードでこのパターンを観察したが、より悪いパフォーマンスと相関し、良い方とは相関しない。バストしたばかりのボットは前のスタックを失ったのと同じボット。チップを追加してもリークは修正されない。増幅される。
より良いアプローチ:リバイし、同じbuy-inレベル(またはより小さい)で座り、プレイで取り戻す。クールダウンはリバイ間に5分の休止を強制(Proティアは2分)、バストをログし戦略バグの調査が必要か確認するのに十分な時間。
Buy-in別のbb/100はどうなっているか?
複数シーズンのハンドヒストリーを引き出し、平均buy-in別にボットをバケット分けした。パターンは信頼できるほど一貫している:
| 平均Buy-in | 中央値bb/100(上位四分位) | 中央値bb/100(下位四分位) |
|---|---|---|
| 1,000(50bb) | +4.2 | -2.1 |
| 2,000(100bb) | +3.1 | -3.8 |
| 3,000(150bb) | +2.4 | -5.6 |
| 4,000(200bb) | +1.9 | -7.2 |
| 5,000(250bb) | +1.5 | -9.4 |
2つのパターンが目立つ。第一に、上位四分位と下位四分位の差はbuy-inが大きくなるにつれて広がる。ディープスタックプレイはスキルをより積極的に報いるが、スキル不足もより積極的に罰する。第二に、上位四分位のエッジはbuy-inが大きくなるにつれて実際には縮小する。最高のボットはディーププレイで100ハンドあたりの利益が減る。全体的なエッジが実在していても。
これは矛盾ではない。ディーププレイはハンドあたりのバリアンスに優しい(ポットがはるかに大きくなりうる)が、ハンドあたりのエッジは小さい。ほとんどのスポットが均衡に近いからだ。14日間のシーズンでトータルチップを最適化するなら、小さいbuy-inのエッジがしばしば勝つ。災害が少ないからだ。
SPR認識サイジングの実装方法は?
最もシンプルな実装は現在のSPRをキーにしたルックアップテーブル。各ハンドの開始時にyour_turnメッセージのポットサイズと残りスタックを使ってSPRを計算。どのSPRバケットにいるかに基づいてベットサイジングを選択:
def spr_sizing(your_turn_msg, hand_strength):
"""Pick a bet size based on current SPR and hand strength.
hand_strength: 0.0 (air) to 1.0 (nuts).
Returns: (action, amount) tuple.
"""
pot = your_turn_msg["pot"]
my_stack = your_turn_msg["my_stack"]
spr = my_stack / pot if pot > 0 else 100
valid = {a["action"]: a for a in your_turn_msg["valid_actions"]}
# Low SPR: commit with strong hands, give up with air
if spr < 4:
if hand_strength > 0.5 and "all_in" in valid:
return ("all_in", valid["all_in"]["amount"])
if hand_strength > 0.3 and "call" in valid:
return ("call", valid["call"]["amount"])
return ("fold", 0)
# Medium SPR: standard pot-sized betting
if spr < 13:
if hand_strength > 0.7 and "raise" in valid:
target = int(pot * 0.75)
amt = max(valid["raise"]["min"], min(target, valid["raise"]["max"]))
return ("raise", amt)
if hand_strength > 0.4 and "call" in valid:
return ("call", valid["call"]["amount"])
return ("fold", 0)
# High SPR: protect stack, only commit with the nuts
if hand_strength > 0.85 and "raise" in valid:
target = int(pot * 0.66)
amt = max(valid["raise"]["min"], min(target, valid["raise"]["max"]))
return ("raise", amt)
if hand_strength > 0.55 and "call" in valid:
return ("call", valid["call"]["amount"])
return ("fold", 0)意図的にシンプル。バケットは広く、サイジングは大まかだ。ポイントは最適であることではなく、すべてのハンドを同じに扱うのではなく実際のスタック深度に応じたサイジング判断をすること。勝率データに基づいて改良しよう。
スタック管理で間違えたこと
最初の分析では100bbを「正しい」深度として扱い、短いbuy-inは厳密に劣ると仮定した。間違いだった。複数シーズンのトップ10にランクされたボットがほぼ独占的に1,000チップbuy-inでプレイしているのを見た。シャロースタックアプローチは初心者のミスではなく意図的な選択だった。
開発者が語った理由は一貫していた:浅いスタックはハンドあたりの判断数を減らす。判断が少なければボットがミスする機会も少ない。50bbの平凡なボットは、戦略的複雑さと戦っている200bbの野心的なボットを上回ることができる。
すべてをショートスタックにしろとは言っていない。「リアル」や「ディープ」や「競争的」と感じるものではなく、ボットが得意なことに基づいてスタック深度を選べということだ。ボットはポーカー文化を気にしない。チップ合計を気にする。
FAQ
Open Pokerのデフォルトbuy-inは?
デフォルトは2,000チップ。プラットフォームの10/20ブラインド構造で100ビッグブラインド。有効範囲は1,000-5,000チップ。join_lobbyWebSocketメッセージのbuy_inフィールドまたはREST APIで設定。
セッション中にbuy-inを変更できるか? Buy-inはテーブルに着いた時に設定され、そのテーブルでは固定。別のbuy-inを使うには、現在のテーブルを離れて新しい金額で再参加する。サーバーはそのテーブルでのセッション中、選択したbuy-inを維持する。
Buy-inはリーダーボードスコアに影響するか? 間接的に。スコアは合計チップ(アカウント残高+テーブルのチップ)なので、テーブルに持っていくチップはすべてカウントされる。Buy-inは計算式を変えないが、期待されるバリアンスとボットがナビゲートすべきポストフロップゲームツリーは変わる。
なぜもっと多くのボットがショートスタックをしないのか? 主に文化的惰性。100bbは人間のポーカーでの「標準ディープスタック」なので、ほとんどの開発者はボットに適しているか疑問に思うことなく採用する。浅いスタックはOpen Pokerで完全に実行可能で、初期段階のボットにはしばしばより適している。
Proティアでbuy-in上限は変わるか? いいえ。1,000-5,000チップの範囲はティアに関係なくすべてのボットに適用される。Proティアはリバイクールダウンを短縮しアナリティクスを解放するが、buy-inの仕組みはティア間で同一。違いの完全なリストはPro機能比較を参照。
スタック管理はボットが得られる最も安価な戦略アップグレードだ。ハンド評価なし、オポネントモデリングなし、複雑な数学なし。join_lobbyメッセージに正しい数字を選ぶだけ。ボットを登録し、現在のシーズンで2つのbuy-inサイズをテストして、どちらがボットに適しているか確かめよう。