德州撲克AI--Programming Poker AI(譯)


 

前言:
  最近在研究德州撲克的AI, 也想由淺入深的看下, 在網上找了一圈, 發現很多文章都提到了一篇文章: Programming Poker AI. 仔細拜讀了一下, 覺得非常不錯. 這里作下簡單的翻譯工作, 可能加些自己的一些理解, 權當做一回大自然的搬運工, ^_^.

 

撲克數據模型抽象(Poker Data Type):
  本文的作者傾向於使用位/字節級別來描述牌的數據模型(Hand=玩家手牌+公共牌), 也算一種高階的抽象.
  花色(Suit), 其值范圍為0..3, 並假定梅花(Clubs)=0, 方塊(Diamonds)=1, 紅心(Hearts)=2, 黑桃(Spades)=3.
  等級(rank), 其值范圍為0..12, 賦予 2(deuce)=0, 3=1, ..., King=11, Ace=12.
  牌(Card)其就對應一個0..51的整數, 三者滿足如下等式:

card = suit*13 + rank.
Suit = card/13
Rank = card%13 

  Hand就可以用一個52bit的表示, 其中每一位都代表一個具體的牌. 可以借用4個16位字節來簡單實現, 其中每個16位字節(word)覆蓋一組花色牌.
  
  對於牌類型(Hand Type), 這邊設定:

高牌(no pair) = 0
一對(pair) = 1
兩對(two pair) = 2
三條(trips) = 3
順子(straight) = 4
同花(flush) = 5
葫蘆(full house) = 6
金剛(quads) = 7
同花順(straight flush) = 8

  注: 這邊的Hand, 我的理解是對應玩家手牌+公共牌組合后的結果.

 

牌力編碼(Encoding Hand Values):
  牌力的編碼可以用32位正整數來標識, 其值的大小和牌力是正相關.
  牌力編碼設計為6個半字節(4位)的組合, 最高的半字節代表牌類型, 接下來的5個半字節代表依序的數值.
  

  樣例一: AH,QD,4S,KH,8C 是高high牌型, 所以牌型半字節為0. 數值排序為(A, K, Q, 8, 4), 其經值轉換后為(12, 11, 10, 6, 2). 用16進制來表示, 則變為(C, B, A, 6, 2). 最終的32位整數為: 0x000CBA62.
  樣例二: 4D,JD,3D,4C,AD 是一對牌型, 所以牌型半字節為1. 數值排序為(4, A, J, 3), 16進制表示為(2, C, 9, 1). 最終的32位整數位: 0x0012C910.
  樣例三: 7C,6C,5C,4C,3D 是順子牌型, 所以牌型半字節為4. 數值排序(7), 16進制表示為(5). 最終的32位整數位: 0x00450000. 注: 順子類型選取最高的數值代表.
  結合這些樣例, 你會發現, 其牌力和代表的數值, 是符合正相關的. 因此牌力的比較變得非常的容易.

 

計算牌力(Calculating Hand Values):
  我們需要定義一個函數, 能夠快速的計算hand到牌力值的轉換. 這邊提供了一些思路.
  比如同一花色的13位可以有8192種組合(2的13次方=8192), 這個數值不大. 它給我們了一種思路去優化計算, 就是提供一個預計算好的8K大小的table表, 用於加速評估. 比如快速找到同花, 順子等等.
  再比如計算每個牌數的不同花色數, 利用有不同花色的rank, 然后快速確定牌型.
  這個函數最終涉及按位操作, 表查詢和簡單比較, 那它的性能將非常的快.

 

計算勝率(Calculating Hand Strength):
  勝率(HS)是一個0.0到1.0之間的一個數值, 它代表贏得當前局的概率. 比如HS=0.33意味着, 33%的概率贏得勝率.
  這邊勝率計算方式, 采用了模擬法(俗稱的蒙特卡洛算法). 比如隨即模擬1000次, 你贏得423局, 那么你的HS為423/1000=0.423.
  這個模擬過程, 可以用如下偽代碼來表示:

Create a pack of cards
Set score = 0
Remove the known cards (your hole cards, and any community cards)
Repeat 1000 times (or more, depending on CPU resources and desired accuracy)
    Shuffle the remaining pack
    Deal your opponent's hole cards, and the remaining community cards
    Evaluate all hands, and see who has the best hands
    If you have the best hand then
        Add 1/(number of people with the same hand value) to your score (usually 1)
    End if
end repeat
Hand Strength = score/number of loops (1000 in this case).

  真實的勝率評估可能要比這要復雜, 你需要考慮其他玩家位置, 行為, 籌碼量, 盲注等. 所以計算勝率的過程, 需要一定程度的修改. 當然這是個開放性的話題. 

 

底池賠率(Pot Odds):
  底池賠率是指你的加注/跟注和最終底池的比例值.
  比如你加注$20, 加注前底池總額為$40. 那么底池賠率為20/(40+20)=0.333.

 

收益率(Rate Of Return):
  收益率也可以稱為回報率, 我們如下定義它:

 Rate Of Return = Hand Strength / Pot Odds.

   

決策(The Fold/Call/Raise Decision):
  定義FCR為每一輪棋牌/跟住/加注的策略行動. 同時定義RR為回報率(Rate Of Return).

If RR < 0.8 then 95% fold, 0 % call, 5% raise (bluff)
If RR < 1.0 then 80%, fold 5% call, 15% raise (bluff)
If RR <1.3 the 0% fold, 60% call, 40% raise
Else (RR >= 1.3) 0% fold, 30% call, 70% raise
If fold and amount to call is zero, then call.

  對於上面的閾值, 可以適當的進行調整.
  同時這邊也加入一些模糊策略, 包括在牌力不強情況下的詐唬.
  注: 這邊的詐唬, 某種角度也可以理解為半詐唬, 是自帶防守, 就算詐唬失敗依舊有機會逆轉.

 

籌碼保護(Stack Protection):
  當你的籌碼很深且盲注很小時, 上述的簡單規則會表現的很出色. 但是自身處於短籌或者盲注變高時, 需要做些保護策略, 否則很容易All-In而失去所有.
  比如你手牌為AD, 2D, 此時公共牌為QC, KC, 2C. 此時你2一對, 但對手可能是同花牌. 如果底池為$500, 而對家raise $100. 剛好你籌碼只有$100. 這種情況下, 你的Pot Odds(底池賠率)為100/(500+100)=0.1666, HS(勝率)為0.297. 這樣RR=0.297/0.1666=1.8, 按照上述決策, 應該call. 但是這種情況下, 你有70%的大概率會失去所有, 請不要這樣決策.
  為了處理這種情況, 引入一個簡答的啟發式條件: 除非大概率勝率, 否則不輕易壓上全部/大部分籌碼.
  添加如下規則:

if (stack- bet) < (blind * 4) and (HS < 0.5) then fold

  

更多的工作(More Work):
  當前的AI策略, 還有如下需要加強的地方:
  1). 翻前手牌勝率預估(Pre-flop hand strength tables)
  2). 對手模型(Opponent modeling)
  3). 隱含賠率(Implied Odds)
  4). 個性化建模(Personality modeling)
  5). 基於位置的策略(Positional play)
  6). 概率搜索空間(Probabilistic search space)
  7). 游戲理論和納什均衡(Game theory and Nash Equilibrium)

 

AI測試:
  總的來說, AI效果還是很贊的. 包括網上的很大大拿, 實現了該算法之后, 都豎起了大拇指. 當然這個算法, 遇到蠻不講理的玩家, 把把All In, 它的棄牌率有些高. 其實真實玩家去玩, 也會是類似的囧境, 只不過人是可以根據對手的打法動態的調整策略, 這一點確實是該AI算法的不足. 還有就是對玩家的反raise, 該算法沒有相應策略應對.

  

評價:
  其實這個AI算法, 最讓我眼前一亮的, 其實是它的數據模型抽象, 以及牌力值函數設計, 對於快速計算也提供一種很好思路, 確實很贊. 算法本身借助蒙特卡洛算法, 隱含了當前牌力/發展面(抽牌命中率), 對手的可能牌力分布, 這些綜合的因素, 完美而簡潔地現實了效果. 總的來說, 這是一個很好的文章, 其數據模型可被后續很多AI算法繼續沿用.

 

個人站點:

  個人游戲作品集站點(尚在建設中...): www.mmxfgame.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM