陳 思
(福州大學(xué) 數(shù)學(xué)與計算機(jī)科學(xué)學(xué)院,福建 福州 350000)
德克薩斯撲克全稱Texas Hold’em poker,中文簡稱“德州撲克”。它是一種玩家對玩家的公共牌類游戲。一張臺面至少2人,最多22人,一般是由2-10人參加。德州撲克一共有52張牌,沒有王牌。每個玩家分兩張牌作為“底牌”,五張由荷官陸續(xù)朝上發(fā)出的公共牌。開始的時候,每個玩家會有兩張面朝下的底牌。經(jīng)過所有押注圈后,若仍不能分出勝負(fù),游戲會進(jìn)入“攤牌”階段,也就是讓所剩的玩家亮出各自的底牌以較高下,持大牌者獲勝。因技巧性強(qiáng),易學(xué)難精又被稱為“撲克游戲中的凱迪拉克”。
在這個游戲里,如何根據(jù)手頭的牌以及桌面上的牌計算概率,成為勝負(fù)的關(guān)鍵。與一副牌的已知牌型計算不同,德州撲克不但需要計算牌型的RANK(即排名)值,更需要計算出當(dāng)前牌型的具體勝率。其中具體的勝率計算非常復(fù)雜,筆者將在本文中探討一種可行的方式。
由于本文為概率計算介紹,不在贅述德州撲克中關(guān)于籌碼的計算規(guī)則,僅把撲克的基本勝負(fù)規(guī)則做一個闡述。
每個玩家擁有兩張底牌,桌面上將陸續(xù)發(fā)至5張公共牌。當(dāng)全部5張公共牌發(fā)完后,玩家用自己的2張底牌和5張公共牌結(jié)合在一起,選出5張牌,不論手中的牌使用幾張(甚至可以不用手中的底牌),湊成最大的成牌,跟其他玩家比大小。
比牌先比牌型,大的牌型大于小的牌型,牌型一般分為10種,從大到小為:皇家同花順(royal flush):由AKQJ10五張組成,并且這5張牌花色相同;同花順(straight flush):由五張連張同花色的牌組成;4條(four of a kind):4張同點(diǎn)值的牌加上一張其他任何牌;滿堂紅(full house)(又稱“葫蘆”):3 張同點(diǎn)值加上另外一對;同花(flush):5 張牌花色相同,但是不成順子;順子(straight):五張牌連張,至少一張花色不同;3條(three of a kind):三張牌點(diǎn)值相同,其他兩張各異;兩對(two pairs):兩對加上一個雜牌;一對(one pair):一對加上 3張雜牌;高牌(high card):不符合上面任何一種牌型的牌型,由單牌且不連續(xù)不同花的組成。
在本文中,筆者們的主要問題就是,需要計算玩家的勝率。換句話來說,假設(shè)當(dāng)玩家持有AK(不同花色)時,桌面上為2,3,4,K,Q,且此時共同游戲的玩家有9名 (即競爭對手有8名),這種情況的勝算是多大,就是筆者們需要計算的值。
由于筆者們對于另外8個競爭對手手上的牌一無所知,計算勝率時,筆者們需要窮舉所有的8名玩家可能出現(xiàn)的所有牌型,并一一分析,最后得出實際勝率。
為了研究簡便,筆者們將游戲被分解為這樣的問題:
1)一副牌中,任意取出五張,需要程序馬上計算出它在所有牌型中的排名;
2)已知七張牌中,計算這7張牌能湊出的最大牌型;
3)根據(jù)當(dāng)前公共牌面、人數(shù),窮舉所有情況,并一一對比從而計算勝率(后續(xù)內(nèi)容將證明這種方式并不科學(xué)并會給出解決方案)。
本論文中將解決以上問題,并編寫為IPHONE APP。解決問題時,考慮到IPHONE處理器的處理水平,解決過程進(jìn)行過專門的優(yōu)化處理。
計算牌型的排名涉及到牌型之間的對比。由于上述的分解步驟中,第三部(即窮舉步)將進(jìn)行大數(shù)量級的牌型對比,在這種對比中,每次都調(diào)用牌型分析函數(shù)是不明智的,筆者們需要將牌型以及其對應(yīng)的排名一次性計算出來,并予以儲存,方便快速調(diào)用。
一副撲克一共有52張,從其中抽出5張的可能性一共有:2598960種可能性。如果將以上情況一一存儲(需要存儲牌值以及排名),至少需要20M左右的存儲空間。這不但會讓整個應(yīng)用程序變的臃腫,更會大幅降低檢索速度。
本文采取的方式如下:
2.1.1 考慮到德州撲克的牌型大小對比時,不考慮花色。即紅桃10JQKA與黑桃的10JQKA被認(rèn)為是一樣大。每次計算某5張牌的值時,用這種方式表示當(dāng)前牌型:
1)不管牌型花色;
2)計算牌型中重復(fù)的牌,并對其計數(shù)。
編碼規(guī)則:
筆者設(shè)立了一個長度為52的數(shù)組,其中0,4,8,12….48所有被4整除的整數(shù)將分別用于代表撲克上的數(shù)字,規(guī)則是n代表(n/4)+1。在這里筆者們將撲克A計數(shù)為1,K計數(shù)為13,Q計數(shù)為12,而J技術(shù)為11。而無法被4整除的數(shù),將用來代表上述數(shù)字的牌面,出現(xiàn)了多少次。
舉例來說:紅桃A,黑桃A,方塊K,梅花K,黑桃6這個牌型,經(jīng)過以上整理,被編碼為:2,50,20。 (例 3.1)
用數(shù)學(xué)表達(dá)來說,假設(shè)編碼后的數(shù)字為i,j,k,則代表原牌型為:
(i%4+1)張的(i-i%4)/4+1,(j%4+1)張的(j-j%4)/4+1,(k%4+1)張的(kk%4)/4+1
從以上例子來看,2,50,20并不僅僅代表紅桃A,黑桃A,方塊K,梅花K,黑桃6這種情況,實際上,它代表了所有一對A,一對K以及一張單張6的牌型而不管花色如何。
2.1.2 為了方便數(shù)據(jù)存儲并保證牌型的唯一性(即確保不一樣的牌型筆者們會以不同的數(shù)據(jù)存儲起來),筆者采用64位隨機(jī)數(shù)來代表所有牌型。
代碼如下:
PNC數(shù)組即代表不同數(shù)字(1-K)以及不同數(shù)量(1張到4張)的所有情況。以之前的“紅桃A,黑桃A,方塊K,梅花K,黑桃6”牌型為例,如果需要將該牌型進(jìn)行唯一標(biāo)識,采取以下方式:
Zobrist=PNC[2]^PNC[20]^PNC[50];//Zobrist即計算出的牌型值,它是唯一的。
2.1.3 有了以上的數(shù)組后,即可以通過遍歷所有牌型情況,給每一種牌型進(jìn)行評分。為了方便計算,采取的方法是將牌型由大到小進(jìn)行排列,將最大的牌型記為1分,第二大的牌型記為2分,相同的牌型分值相同,以此類推。
相關(guān)代碼示例如下:
根據(jù)2.1節(jié)所述,我們可以知道當(dāng)所有桌面牌都被發(fā)下后,可以通過簡單的排列組合得出手上兩張牌與桌面5張牌結(jié)合中最大的牌型,舉例來說:
玩家手牌:紅桃K,黑桃A
桌面牌:梅花 K,方塊K,紅桃Q,黑桃 J,方塊 10
則最大牌型為順子,即:黑桃A,方塊K(或者其他兩色K),紅桃Q,黑桃J,方塊10。接下來,需要根據(jù)手頭的牌型以及桌面的5張牌,計算勝率。由于德州撲克的復(fù)雜性,前面說到,如果要精確計算概率,那么其數(shù)量級是非常龐大的,當(dāng)玩家超過3名以后,當(dāng)前的計算機(jī)也無法完成這樣的計算任務(wù)。(具體算法如下)
一般德州撲克的玩家是6名以上,這樣計算勝率根本是不現(xiàn)實的。但是,我們注意到,概率計算除了精確計算以外,我們可以采取非精確估計法。
舉例來說,玩家的某個牌型,我們并不清楚其究竟是否會獲勝,我們可以隨機(jī)生成其余玩家的牌型,我們把生成完畢的情況稱為一組牌局,每隨機(jī)生成一組牌局,我們就對比當(dāng)前玩家與其他隨機(jī)生成玩家的牌型,以計算當(dāng)前玩家是否獲勝,如果獲勝,就把勝利局?jǐn)?shù)計數(shù)器加1,當(dāng)模擬牌局?jǐn)?shù)量超過某個值時,計算模擬局中當(dāng)前玩家獲勝的次數(shù)與總牌局?jǐn)?shù)量的比值,即為我們想要的勝率。
這樣,我們將一個天文數(shù)字的牌局對比,下降到計算機(jī)可以接受的程度,以6名玩家為例,總共需要計算的牌型情況為:
如果我們設(shè)置總局?jǐn)?shù)為10000局,則計算總數(shù)為1260000,該數(shù)量級對于計算機(jī)來說非常輕松,實際測試中,一臺普通配置的個人電腦可以在3秒內(nèi)完成該計算。局?jǐn)?shù)越多,則計算出的概率與實際值就越接近,根據(jù)2玩家小規(guī)模測試,總局?jǐn)?shù)在2000局以上時,計算出的概率已經(jīng)非常接近于真實值,局?jǐn)?shù)大幅增加雖然讓數(shù)字更加接近,但實際意義并不大。
通過牌型的存儲與計算以及一種基于概率的非精確算法,我們從一定程度上解決了德州撲克的概率問題,在實際應(yīng)用中,我們發(fā)現(xiàn)這種方法的準(zhǔn)確率較高,已經(jīng)可以從一定意義上指導(dǎo)牌局。當(dāng)然,隨著技術(shù)的發(fā)展,應(yīng)該會有更加先進(jìn)的算法出現(xiàn),本文所述的方法也仍有一定的提升空間(如加大模擬局的總數(shù),采取后臺計算等等),后續(xù)筆者會持續(xù)跟進(jìn)本項目研究。