日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php麻将机器人ai算法,高性能麻将AI算法

發布時間:2025/3/20 php 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php麻将机器人ai算法,高性能麻将AI算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

想要一個高性能的麻將AI算法,這個問題我們拆解成2個子集來思考,“高性能”,“麻將AI算法”,我們先針對麻將AI算法來討論。

麻將AI

“麻將AI”,什么樣的才叫AI,在很多項目中,并不嚴格要求可以與人類頂尖高手pk能力的AI,而是麻將選手陪玩機器人,基本做到一般人類選手的水平。那么這個問題我們可以繼續修改“一般能力麻將AI”。

現在我們來繼續分解這個“一般能力麻將AI”,我們可以把這個AI變成”一個不懂得算桌子上牌,只會盯著自己牌的選手,然后可以得出我打出哪張牌后,我胡牌幾率最大的人”。

根據上篇的,麻將胡牌算法我們可以得出,如果想得出“胡牌”的概念可以用得到3N的牌面以及3N+2的說法替代。所以這個時候問題變成“只會盯著自己牌的選手,針對同一種花色,計算出這個花色的牌打出一張后,變成3N或者3N+2的幾率多大”。

此時就有一個問題了,針對一種花色在很多牌面中,我打出一張牌的張數并不是3N或者3N+2,這個時候怎么辦?這里可以用到一個近似解,“在某個特定的array中,我需要補多少張,才可以得到3N或者3N+2的組合”,為了簡單說明起見,后續只說明如何構造3N的牌型。

這個時候還剩下最后一個問題了,概率問題如何結算,這個可以通過回溯來求去最大解,來了牌值大小為1到9的一個集合,每次抽取1張,然后可以構成3N,需要抽取多輪。這個就是個9叉樹,然后通過一定的剪枝手段來控制樹的總大小。偽代碼如下

// array 表示手牌,level代表補的張數

// 1/chance表示概率,所以chance表示為概率的倒數

// chance = chance * 136 / 4。表示136張牌中來這張牌概率,這里可以優化下改成當前

// 牌里剩下的張數在出于牌堆總數,這里為了表達方便,直接用 136 / 4,可以優化這個常量,

// 比如,136按照扣除自己手牌數136-13*4計算,

//4可以用 4-自己手牌的張數這個數來替代,這樣AI就是個會算自己手牌

// 的機器人了,不會導致說自己手牌中有4個一萬,還是來一萬胡牌概率高的情況

//發生了,如果優化136 / 4 這個常量,會針對不可能不到的情況,會剪枝了,也減少會一定的運算。

//計算牌的概率

getchance(array,level,chance)

//大于等于6一定要剪枝,不可能需要大于6的情況存在,補的最多的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表來查詢,所以本質是個O(1)的操作

if array[i] <= 4

if check3N(array)

chance = chance * 4/136

//如果優化修改4/136 這個常量,需要求去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 // 這里可以把array的key以及概率寫入data文件

計算3N2的概率,只需要把上述代碼中check3N改成check3N2即可。

下面給出會計算getchance的優化版本,可以算自己手牌了。

//計算牌的概率

getchance(array,level,chance)

//大于等于6一定要剪枝,不可能需要大于6的情況存在,補的最多的6張,要只有 1 3 7 這種情況

if(level >= 6) return MAX

if check3N(array) return 1,0 //表示該組合已經是3N了,不需要打出牌

//定義

maxchance = 0

for i =1 to 9

left = 4 - array[i]

array[i] = array[i]+1

//這里check3N直接用上篇用工具生成的3N的hash表來查詢,所以本質是個O(1)的操作

//上述算法中的136 這個稍微準確點改成83稍微更準確點,136-13*3-14 = 83,這個值只會小于83的,但是不論136

//還是83都不影響本質

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還剩幾張可以提供給我,這里沒計算別人打出去的牌

這個也是此算法不夠智能的地方,因為別人打出去的牌是動態的,事先生成data只能看靜態數據,這樣可以選取一張打出去某張牌,獲取胡牌概率可以做到O(1)。

如果想智能高一點,可以服務器運行過程中跑這個算法,動態的計算出left以及83這個常量,就更能準確的提高AI智能了,但是換來了,服務器計算資源的犧牲,確實沒有兩全起美的辦法。

高性能

上述的代碼中已經給我們生成好了組成當前牌組成3N以及3N2的概率的data,當服務器啟動時,就可以把data讀入內存,構建hash表。

服務器判定到底出那張的偽代碼如下

//針對同一種花色的數組中,計算出打出某一張牌可以得到3n 以及3n2的最大概率

outcard(array)

//定義最大3n概率以及最大概率下應出的牌 max3nchance max3n_i

//定義最大3n2概率以及最大概率下應出的牌 max3n2chance max3n2_i

for i=1 to 9

if array[i] > 0

array[i] = array[i] - 1 //先扣掉出的牌

//獲取當前花色的牌構建出3n的概率 直接從上述代碼data文件中的哈希表查詢

chance3n = get3nchace(array)

if chance3n > max3nchance

max3nchance = chance3n

max3n_i = i

//獲取當前花色的牌構建出3n2的概率 直接從上述代碼data文件中的哈希表查詢

chance3n2 = get3n2chace(array)

if chance3n2 > max3n2chance

max3n2chance = chance3n2

max3n_i = i

array[i] = array[i] + 1 //恢復

return max3nchance,max3n_i,max3n2chance,max3n2_i

最終計算胡牌,計算出選取一個3n2以及剩下花色3n的總體概率最大值即可,此時就找到了應該打出哪一張牌,其實針對碰杠吃的做法也一樣

碰了后能不能讓我贏面最大,只是這里扣除一張牌,改成扣除碰的牌來判斷而已。

此時麻將AI已經有了非常高的性能以及智能,幾乎模擬了“一個會算自己手牌,但是不會看桌子上牌的”人類玩家。

因為很多項目中,對性能要求很高,并不是1V1的AI,可能需要幾萬個AI陪玩機器人來陪玩,所以高性能是必須的。

總結

以上是生活随笔為你收集整理的php麻将机器人ai算法,高性能麻将AI算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。