php麻将机器人ai算法,高性能麻将AI算法
想要一個(gè)高性能的麻將AI算法,這個(gè)問題我們拆解成2個(gè)子集來思考,“高性能”,“麻將AI算法”,我們先針對(duì)麻將AI算法來討論。
麻將AI
“麻將AI”,什么樣的才叫AI,在很多項(xiàng)目中,并不嚴(yán)格要求可以與人類頂尖高手pk能力的AI,而是麻將選手陪玩機(jī)器人,基本做到一般人類選手的水平。那么這個(gè)問題我們可以繼續(xù)修改“一般能力麻將AI”。
現(xiàn)在我們來繼續(xù)分解這個(gè)“一般能力麻將AI”,我們可以把這個(gè)AI變成”一個(gè)不懂得算桌子上牌,只會(huì)盯著自己牌的選手,然后可以得出我打出哪張牌后,我胡牌幾率最大的人”。
根據(jù)上篇的,麻將胡牌算法我們可以得出,如果想得出“胡牌”的概念可以用得到3N的牌面以及3N+2的說法替代。所以這個(gè)時(shí)候問題變成“只會(huì)盯著自己牌的選手,針對(duì)同一種花色,計(jì)算出這個(gè)花色的牌打出一張后,變成3N或者3N+2的幾率多大”。
此時(shí)就有一個(gè)問題了,針對(duì)一種花色在很多牌面中,我打出一張牌的張數(shù)并不是3N或者3N+2,這個(gè)時(shí)候怎么辦?這里可以用到一個(gè)近似解,“在某個(gè)特定的array中,我需要補(bǔ)多少?gòu)?#xff0c;才可以得到3N或者3N+2的組合”,為了簡(jiǎn)單說明起見,后續(xù)只說明如何構(gòu)造3N的牌型。
這個(gè)時(shí)候還剩下最后一個(gè)問題了,概率問題如何結(jié)算,這個(gè)可以通過回溯來求去最大解,來了牌值大小為1到9的一個(gè)集合,每次抽取1張,然后可以構(gòu)成3N,需要抽取多輪。這個(gè)就是個(gè)9叉樹,然后通過一定的剪枝手段來控制樹的總大小。偽代碼如下
// array 表示手牌,level代表補(bǔ)的張數(shù)
// 1/chance表示概率,所以chance表示為概率的倒數(shù)
// chance = chance * 136 / 4。表示136張牌中來這張牌概率,這里可以優(yōu)化下改成當(dāng)前
// 牌里剩下的張數(shù)在出于牌堆總數(shù),這里為了表達(dá)方便,直接用 136 / 4,可以優(yōu)化這個(gè)常量,
// 比如,136按照扣除自己手牌數(shù)136-13*4計(jì)算,
//4可以用 4-自己手牌的張數(shù)這個(gè)數(shù)來替代,這樣AI就是個(gè)會(huì)算自己手牌
// 的機(jī)器人了,不會(huì)導(dǎo)致說自己手牌中有4個(gè)一萬,還是來一萬胡牌概率高的情況
//發(fā)生了,如果優(yōu)化136 / 4 這個(gè)常量,會(huì)針對(duì)不可能不到的情況,會(huì)剪枝了,也減少會(huì)一定的運(yùn)算。
//計(jì)算牌的概率
getchance(array,level,chance)
//大于等于6一定要剪枝,不可能需要大于6的情況存在,補(bǔ)的最多的6張,要只有 1 3 7 這種情況
if(level >= 6) return MAX
if check3N(array) return chance
for i =1 to 9
array[i] = array[i]+1
//這里check3N直接用上篇用工具生成的3N的hash表來查詢,所以本質(zhì)是個(gè)O(1)的操作
if array[i] <= 4
if check3N(array)
chance = chance * 4/136
//如果優(yōu)化修改4/136 這個(gè)常量,需要求去1到9中值的最大概率
return chance
else
chance = dfs(array,level+1,chance)
array[i] = array[i]-1
return chance
//生成概率data
gen_chance()
//定義array
for j=1 to 4
for i=1 to 9
array[i] = array[i] + 1
chance = getchance(array)
print chance // 這里可以把a(bǔ)rray的key以及概率寫入data文件
計(jì)算3N2的概率,只需要把上述代碼中check3N改成check3N2即可。
下面給出會(huì)計(jì)算getchance的優(yōu)化版本,可以算自己手牌了。
//計(jì)算牌的概率
getchance(array,level,chance)
//大于等于6一定要剪枝,不可能需要大于6的情況存在,補(bǔ)的最多的6張,要只有 1 3 7 這種情況
if(level >= 6) return MAX
if check3N(array) return 1,0 //表示該組合已經(jīng)是3N了,不需要打出牌
//定義
maxchance = 0
for i =1 to 9
left = 4 - array[i]
array[i] = array[i]+1
//這里check3N直接用上篇用工具生成的3N的hash表來查詢,所以本質(zhì)是個(gè)O(1)的操作
//上述算法中的136 這個(gè)稍微準(zhǔn)確點(diǎn)改成83稍微更準(zhǔn)確點(diǎn),136-13*3-14 = 83,這個(gè)值只會(huì)小于83的,但是不論136
//還是83都不影響本質(zhì)
if array[i] <= 4
if check3N(array) AND left > 0
chance = chance * left/83
if chance > maxchance
maxchance = chance
else
chance = dfs(array,level+1,chance* left/83)
if chance > maxchance
maxchance = chance
array[i] = array[i]+1
return maxchance
left還剩幾張可以提供給我,這里沒計(jì)算別人打出去的牌
這個(gè)也是此算法不夠智能的地方,因?yàn)閯e人打出去的牌是動(dòng)態(tài)的,事先生成data只能看靜態(tài)數(shù)據(jù),這樣可以選取一張打出去某張牌,獲取胡牌概率可以做到O(1)。
如果想智能高一點(diǎn),可以服務(wù)器運(yùn)行過程中跑這個(gè)算法,動(dòng)態(tài)的計(jì)算出left以及83這個(gè)常量,就更能準(zhǔn)確的提高AI智能了,但是換來了,服務(wù)器計(jì)算資源的犧牲,確實(shí)沒有兩全起美的辦法。
高性能
上述的代碼中已經(jīng)給我們生成好了組成當(dāng)前牌組成3N以及3N2的概率的data,當(dāng)服務(wù)器啟動(dòng)時(shí),就可以把data讀入內(nèi)存,構(gòu)建hash表。
服務(wù)器判定到底出那張的偽代碼如下
//針對(duì)同一種花色的數(shù)組中,計(jì)算出打出某一張牌可以得到3n 以及3n2的最大概率
outcard(array)
//定義最大3n概率以及最大概率下應(yīng)出的牌 max3nchance max3n_i
//定義最大3n2概率以及最大概率下應(yīng)出的牌 max3n2chance max3n2_i
for i=1 to 9
if array[i] > 0
array[i] = array[i] - 1 //先扣掉出的牌
//獲取當(dāng)前花色的牌構(gòu)建出3n的概率 直接從上述代碼data文件中的哈希表查詢
chance3n = get3nchace(array)
if chance3n > max3nchance
max3nchance = chance3n
max3n_i = i
//獲取當(dāng)前花色的牌構(gòu)建出3n2的概率 直接從上述代碼data文件中的哈希表查詢
chance3n2 = get3n2chace(array)
if chance3n2 > max3n2chance
max3n2chance = chance3n2
max3n_i = i
array[i] = array[i] + 1 //恢復(fù)
return max3nchance,max3n_i,max3n2chance,max3n2_i
最終計(jì)算胡牌,計(jì)算出選取一個(gè)3n2以及剩下花色3n的總體概率最大值即可,此時(shí)就找到了應(yīng)該打出哪一張牌,其實(shí)針對(duì)碰杠吃的做法也一樣
碰了后能不能讓我贏面最大,只是這里扣除一張牌,改成扣除碰的牌來判斷而已。
此時(shí)麻將AI已經(jīng)有了非常高的性能以及智能,幾乎模擬了“一個(gè)會(huì)算自己手牌,但是不會(huì)看桌子上牌的”人類玩家。
因?yàn)楹芏囗?xiàng)目中,對(duì)性能要求很高,并不是1V1的AI,可能需要幾萬個(gè)AI陪玩機(jī)器人來陪玩,所以高性能是必須的。
總結(jié)
以上是生活随笔為你收集整理的php麻将机器人ai算法,高性能麻将AI算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php5.23升级,2018年5月5号2
- 下一篇: MATLAB中cfl,ML4835复合P