血战麻将算法
1.????? 算法簡(jiǎn)介
本文的麻將算法不是按人工智能的方式進(jìn)行講解,本人從事游戲服務(wù)器開發(fā)。所以該算法主要用于一般的麻將游戲機(jī)器人,主要是讓機(jī)器人具有正常操作選擇。算法無(wú)法與現(xiàn)實(shí)生活中的麻將高手進(jìn)行對(duì)決,也沒有經(jīng)過(guò)嚴(yán)格的數(shù)學(xué)論證,但是為了應(yīng)付麻將高手,會(huì)采取一些作弊的手段。所以本文除了講述麻將算法,還將會(huì)提及麻將作弊的方式,以及該算法應(yīng)用到實(shí)際機(jī)器人中對(duì)于機(jī)器人的等級(jí)劃分方法。
該算法的核心宗旨是以權(quán)值驅(qū)動(dòng)操作。所以本文將主要講述從如何合理的精確的計(jì)算權(quán)值。以及在加入作弊因素情況下的權(quán)值計(jì)算方式。
?
2.????? 麻將算法
麻將算法的設(shè)計(jì)我們將采用貪心算法,即讓機(jī)器人做出當(dāng)前情況下最好的選擇。
血戰(zhàn)麻將:共108張. 萬(wàn)36張, 筒36, 條36張。
麻將過(guò)程中的操作:選缺牌,碰牌, 杠牌,胡牌, 出牌, 過(guò)。
2.1權(quán)值定義
權(quán)值設(shè)置說(shuō)明:根據(jù)血戰(zhàn)麻將規(guī)則定義相同花色相隔的牌為最小權(quán)值單元,定義權(quán)值為1.
手牌權(quán)值計(jì)算方法:基礎(chǔ)權(quán)值+加成權(quán)值。
基礎(chǔ)權(quán)值:相隔+1, 相鄰+2, 2張相同+2,? 3張相同+3,?? 4張相同+4,基礎(chǔ)全職計(jì)算對(duì)象包括手牌和碰牌以及杠牌,但是杠牌和碰牌以及收必須進(jìn)行分開計(jì)算。
加成權(quán)值:牌張數(shù)加成,風(fēng)險(xiǎn)加成
牌張數(shù)加成:根據(jù)當(dāng)前花色牌的張數(shù)比,對(duì)當(dāng)前花色權(quán)值進(jìn)行加成。
定義萬(wàn)張數(shù)為x,定義萬(wàn)基礎(chǔ)權(quán)值為y,則萬(wàn)牌張數(shù)加成權(quán)值z(mì)=y*(1+x/14);
風(fēng)險(xiǎn)加成:根據(jù)當(dāng)前已知情況,出牌,碰牌,杠牌,胡牌所帶來(lái)的風(fēng)險(xiǎn)對(duì)手牌權(quán)值和進(jìn)行加成。定義:定義當(dāng)前手牌牌張數(shù)加成后權(quán)值和為m,當(dāng)前牌的風(fēng)險(xiǎn)系數(shù)為β,則風(fēng)險(xiǎn)系數(shù)加成后的權(quán)值n= m*(1+β);
?
2.2基礎(chǔ)操作
?
本節(jié)根據(jù)玩家出牌動(dòng)作對(duì)權(quán)值(不含風(fēng)險(xiǎn)加成)進(jìn)行說(shuō)明。
2.2.1??????? 基礎(chǔ)權(quán)值與張數(shù)加成
1.基礎(chǔ)權(quán)值計(jì)算演示
2筒權(quán)值:與3筒相鄰+2, 與4筒相隔+1, 共:2+1=3
3筒權(quán)值:與2筒相鄰+2,與4筒相鄰+2,與5筒相隔+1,共:2+2+1=5
4筒權(quán)值:與2筒相隔+1,與3筒相鄰+2,與5筒相鄰+2,共:1+2+2=5
5筒權(quán)值:與4筒相鄰+2, 與3筒相隔+1, 共:2+1=3
4張牌權(quán)值和:3+5+5+3=16
?
3條權(quán)值:與3個(gè)3條4張相同+12,與5條相隔+1 共12+1=13
5條權(quán)值:與4個(gè)三條相隔+4 共:4
5張牌權(quán)值和:4*13 +4 = 56
?
2筒權(quán)值:無(wú)相鄰,相同,相隔,權(quán)值為0
5筒權(quán)值:0
9筒:與1個(gè)2張相同+2;共2
總共權(quán)值:0+0+2*2 = 4
說(shuō)明:權(quán)值為0的牌將在牌張數(shù)上面提升筒色整體權(quán)值。
?
條權(quán)值計(jì)算:
3條權(quán)值:與3個(gè)3條4張相同+12,共12
7天權(quán)值:與8條相鄰+2
8條權(quán)值:與7條相鄰+2
?
所有條的基礎(chǔ)權(quán)值:4*12 + 2 + 2 =52
?
所有筒的權(quán)值:3(1筒)+3(1筒)+3(3筒)+ 3(4筒) +2(6筒) +3(8筒) +2(9筒) = 19
所有條的權(quán)值:2(1條) +3(2條)+ 4(4條) +5(5條) +5(6條) +3(7條)=17
筒基礎(chǔ)權(quán)值:19
條基礎(chǔ)權(quán)值:17
牌張數(shù)加成后權(quán)值:筒權(quán)值:19*(1+7/14)=28?? 條權(quán)值:17*(1+6/14)=24
所有手牌加成后的權(quán)值和:28+24=52
?
2.2.2??????? 缺色操作
選擇方式:分別計(jì)算法萬(wàn)筒條的權(quán)值A(chǔ),B,C,
計(jì)算:
A=(2+2+1+1)*(1+4/14)=7
B=(2+2)*(1+4/14)=5
C=(13+13+13+13+5+1)*(1+6/14)=82
?
選擇權(quán)值最低的花色進(jìn)行定缺:B權(quán)值最小,所以選擇缺筒。
選擇缺牌后,手牌權(quán)值將不計(jì)算缺牌權(quán)值
2.2.3??????? 有缺色出牌操作
直接出缺色牌。占時(shí)不考慮策略,直接按順序出,或者隨機(jī)出。
?
2.2.4??????? 無(wú)卻色出牌操作
選擇方式:計(jì)算每張手牌X打出后,剩余牌的權(quán)值A(chǔ)。然后選擇權(quán)最高的牌打出。
出2筒后權(quán)值和:(3+4+4+3+3+3)*(1+6/14)+ (12+12+12+12+1+3+2)*(1+8/14)=112
出1條后權(quán)值和:(3+5+5+4+3+3+3)*(1+7/14)+(12+12+12+12+1+3+2)*(1+7/14)=120
?
以此類推:計(jì)算法結(jié)束后, 選擇A_max 對(duì)應(yīng)的X牌打出。
?
?
2.2.5??????? 碰牌操作
碰牌選擇:計(jì)算現(xiàn)有權(quán)值A(chǔ),計(jì)算法碰后最佳出牌的權(quán)值B,按照2.2.4中出牌方式計(jì)算即可。
如果A > B 則不碰,如果A <= B 碰,
A=(3+5+6+6+5+5+3+3)*(1+8/14) + (12+12+12+12+2+2)*(1+6/14)=130
B值計(jì)算:
?
2.2.6??????? 杠牌操作
暗杠:
暗杠選擇:計(jì)算暗杠后權(quán)值A(chǔ),計(jì)算放棄杠后最佳出牌的權(quán)值B,如果A>=B則杠,否則放棄。
明杠:
明杠選擇:計(jì)算明杠后權(quán)值A(chǔ),計(jì)算現(xiàn)在有權(quán)值B,如果A>=B則杠,否則放棄。
?
補(bǔ)杠:
補(bǔ)杠選擇:筒暗杠方式進(jìn)行計(jì)算。
?:是否只有門派才能補(bǔ)杠,目前決豆麻將非門也能補(bǔ)杠。
?
2.2.7??????? 胡牌操作
自摸:
自摸選擇:計(jì)算胡牌權(quán)值A(chǔ), 計(jì)算放棄胡牌后最佳出牌權(quán)值B, 如果A>=B,則胡,否則放棄。
炮牌:
炮牌選擇:計(jì)算胡牌權(quán)值,計(jì)算當(dāng)前權(quán)值B, 如果A>=B則選擇胡,否則放棄。
?
2.2.8??????? 多選擇混合操作
同時(shí)可以進(jìn)行出牌, 碰,杠,胡等操作組合。
選擇方式:計(jì)算每種選擇的權(quán)值以及放棄選擇的最佳權(quán)值進(jìn)行比較,選擇權(quán)值最高的操作。
?
?
2.3風(fēng)險(xiǎn)加成
風(fēng)險(xiǎn)加成,麻將過(guò)程風(fēng)險(xiǎn)就是對(duì)輸贏大小的預(yù)估。簡(jiǎn)單的來(lái)說(shuō)輸?shù)姆瑪?shù)和贏的番數(shù)。在血戰(zhàn)麻將中輸贏來(lái)源于兩種情況:杠和胡。所以風(fēng)險(xiǎn)系數(shù)β將根據(jù)其輸贏的番數(shù)進(jìn)行定義。
風(fēng)險(xiǎn)系數(shù)由風(fēng)險(xiǎn)發(fā)生的概率和風(fēng)險(xiǎn)發(fā)生的結(jié)果決定。
定義
風(fēng)險(xiǎn)系數(shù):β
定義當(dāng)前手牌張數(shù)加成后權(quán)值和:m
定義當(dāng)前手牌風(fēng)險(xiǎn)加成后的權(quán)值:n
定義出牌被杠的風(fēng)險(xiǎn)系數(shù)為:a(-1<a<=0)
定義出牌可能點(diǎn)炮的風(fēng)險(xiǎn)系數(shù)為:b(-1<b<=0)
定義叫牌胡牌的風(fēng)險(xiǎn)系數(shù)為:c(0=<c<1)
則
β = a + b + c
n = m*(1+β) = m*(1+a+b+c);
2.3.1??????? 杠牌風(fēng)險(xiǎn)
杠牌風(fēng)險(xiǎn),
定義杠牌風(fēng)險(xiǎn)為:a
定義可能被杠牌概率為:x(0<=x<=1)
定義被杠后輸?shù)姆瑪?shù):y(y=1)
定義比賽封頂番數(shù):z
則:a=0-x*(y/z)
?
x計(jì)算:
定義出牌為A,定義對(duì)手中需要A牌花色的有k(0<=k<=3)家。
1.?????? 如果A已經(jīng)出現(xiàn)過(guò),則x=0
2.?????? 如果A未出現(xiàn)過(guò),則x=k/4
?
?
2.3.2??????? 炮牌風(fēng)險(xiǎn)
炮牌風(fēng)險(xiǎn),
定義炮牌風(fēng)險(xiǎn)為:b
定義比賽封頂番數(shù):z
?
點(diǎn)炮需要分別計(jì)算出牌對(duì)上家,對(duì)家,下家的風(fēng)險(xiǎn)技術(shù)。
定義上家的點(diǎn)炮概率和點(diǎn)炮番數(shù)以及下叫概率分別為x1,y1,t1
定義上家的點(diǎn)炮概率和點(diǎn)炮番數(shù)以及下叫概率分別為x2,y2,t2
定義上家的點(diǎn)炮概率和點(diǎn)炮番數(shù)以及下叫概率分別為x3,y3,t3
則:b=0-(x1*t1*(y1/z)+ x2*t2*(y2/z)+ x2*t3*(y2/z))
?
y1即為玩家牌面可見最大番數(shù)。(1<=y1<=z)
X1與t1的計(jì)算法
定義出牌為A
1.如果上家缺A花色或者玩家已胡則x1=0;
2.如果上家需要A的花色則x1=1/18,t1=1/2
對(duì)家和下家計(jì)算法方式相同。
?
2.3.3??????? 胡牌風(fēng)險(xiǎn)
胡牌風(fēng)險(xiǎn)
定義胡牌風(fēng)險(xiǎn)為:c
定義比賽封頂番數(shù):z
定義叫牌分別為:???????? B1,B2…..Bn
定義叫牌自摸番數(shù):? y1, y2,…yn
定義叫牌自摸的概率:x1, x2….xn
定義玩家吃炮的番數(shù):m1,m2…mn
定義玩家吃炮的概率:n1, n2…nn
定義叫牌的風(fēng)險(xiǎn)概率:c1, c2…cn
?
則:c1=x1*(y1/z) +m1*(n1/z)
c=c1+c2…cn
y1與m1即胡牌的番數(shù)。
x1與n1的計(jì)算:
定義叫牌為B1牌,
定義對(duì)手中需要B1牌牌色的家數(shù)為k(0<=k<=3),
定義已胡牌家數(shù):l(0<=l<=2)
定義已胡家數(shù)中需要A牌牌色的家數(shù):p(0<=p<=l)
定義A牌剩余張數(shù)為j(0<=j<=4)
1.?????? 如果j=0? 則x1=0,n1=0;
2.?????? 如果j>0, ?則x1=(4-k)/4*(1/(4-p))*j, n1=((4-k)/4)*((3-p)/(4-p))*j
?
其他計(jì)算法方式相同。
?
3.????? 麻將作弊
在了解算法后,我們知道我們無(wú)法控制我們的機(jī)器人有絕對(duì)優(yōu)勢(shì)打贏真正的玩家,所以我們需要服務(wù)器作弊進(jìn)行配合,以下是具體方式。
1.機(jī)器人知道所有人的牌,讓機(jī)器人對(duì)其他人進(jìn)行全透視,這樣可以精確計(jì)算杠碰炮胡的權(quán)值。(增加透視性,加大權(quán)值的高可靠性)
2.服務(wù)器在機(jī)器人定缺后,可以根據(jù)機(jī)器人的等級(jí)降低機(jī)器人獲取得廢牌的概率。
3.機(jī)器人下叫后讓機(jī)器人快速的獲取叫牌,機(jī)器人如果獲取的叫牌需要智能換叫。
4.胡牌的大小,讓機(jī)器人胡大牌時(shí),為機(jī)器人配牌,配青一色,配大對(duì)子,增加機(jī)器人杠牌等。
以上所有的更改都是更加機(jī)器人等級(jí)對(duì)應(yīng)的概率進(jìn)行調(diào)整,概率可以小于0,這樣就可以讓機(jī)器人比正常的打牌能力更低。
可以簡(jiǎn)單的總結(jié)為以下幾點(diǎn):
1.增加機(jī)器人透視性,讓其知道所有人的手牌。
2.服務(wù)器配合發(fā)票,配牌。提高機(jī)器人獲取好牌的概率
3.機(jī)器人需要在其現(xiàn)有的透視性基礎(chǔ)上進(jìn)行權(quán)值計(jì)算。
?
4.1透視性與風(fēng)險(xiǎn)加成
服務(wù)器作弊對(duì)機(jī)器人算法唯一有影響的地方就是風(fēng)險(xiǎn)加成, 因?yàn)樵诓恢榔渌伺频臅r(shí)候是按照概率對(duì)風(fēng)險(xiǎn)進(jìn)行評(píng)估的。現(xiàn)在有了準(zhǔn)確的數(shù)據(jù),那么風(fēng)險(xiǎn)加成算法將直接更加數(shù)據(jù)準(zhǔn)確評(píng)估。
?
4.1.1??????? 杠牌風(fēng)險(xiǎn)
杠牌風(fēng)險(xiǎn),
定義杠牌風(fēng)險(xiǎn)為:a
定義可能被杠牌概率為:x(0<=x<=1)
定義被杠后輸?shù)姆瑪?shù):y(y=1)
定義比賽封頂番數(shù):z
則:a=0-x*(y/z)
?
x計(jì)算:
定義出牌為A,定義對(duì)手中需要A牌花色的有k(0<=k<=3)家。
3.?????? 如果A已經(jīng)出現(xiàn)過(guò),則x=0
4.?????? 如果有玩家能杠,則x=1
?
?
4.1.2??????? 炮牌風(fēng)險(xiǎn)
炮牌風(fēng)險(xiǎn),
定義炮牌風(fēng)險(xiǎn)為:b
定義比賽封頂番數(shù):z
?
點(diǎn)炮需要分別計(jì)算出牌對(duì)上家,對(duì)家,下家的風(fēng)險(xiǎn)技術(shù)。
定義上家的點(diǎn)炮概率和點(diǎn)炮番數(shù)以及下叫概率分別為x1,y1,t1
定義上家的點(diǎn)炮概率和點(diǎn)炮番數(shù)以及下叫概率分別為x2,y2,t2
定義上家的點(diǎn)炮概率和點(diǎn)炮番數(shù)以及下叫概率分別為x3,y3,t3
則:b=0-(x1*t1*(y1/z)+ x2*t2*(y2/z)+ x2*t3*(y2/z))
?
定義出牌為A
y1即為玩家胡A牌的番數(shù)。(1<=y1<=z)
X1與t1的計(jì)算法
1.?????? 如果上家無(wú)叫或者玩家已胡則x1=0;
2.?????? 如果A不是上家的叫牌,則x1=0
3.?????? 如果A是上家的叫牌,則x1=1
對(duì)家和下家計(jì)算法方式相同。
?
4.1.3??????? 胡牌風(fēng)險(xiǎn)
胡牌風(fēng)險(xiǎn)
定義胡牌風(fēng)險(xiǎn)為:c
定義比賽封頂番數(shù):z
定義叫牌分別為:???????? B1,B2…..Bn
定義叫牌自摸番數(shù):? y1, y2,…yn
定義叫牌自摸的概率:x1, x2….xn
定義玩家吃炮的番數(shù):m1,m2…mn
定義玩家吃炮的概率:n1, n2…nn
定義叫牌的風(fēng)險(xiǎn)概率:c1, c2…cn
?
則:c1=x1*(y1/z) +m1*(n1/z)
c=c1+c2…cn
y1與m1即胡牌的番數(shù)。
x1與n1的計(jì)算:
定義叫牌為B1牌,
定義對(duì)手中需要B1牌牌色的家數(shù)為k(0<=k<=3),
定義已胡牌家數(shù):l(0<=l<=2)
定義已胡家數(shù)中需要A牌牌色的家數(shù):p(0<=p<=l)
定義A牌剩余張數(shù)為j(0<=j<=4)(可以準(zhǔn)備計(jì)算)
3.?????? 如果j=0? 則x1=0,n1=0;
4.?????? 如果j>0,? 則x1=(4-k)/4*(1/(4-p))*j, n1=((4-k)/4)*((3-p)/(4-p))*j
?
其他計(jì)算法方式相同。
?
?
4.????? 機(jī)器人策略和目標(biāo)
從上述的麻將算法中,我們可以看出每次的選擇都會(huì)進(jìn)行大量的計(jì)算。在真人麻將的過(guò)程中玩家并不需要進(jìn)行很多大量的計(jì)算,應(yīng)該玩家會(huì)有自己的策略和目標(biāo),
在擁有目標(biāo)后很多因素是不用考慮的,這樣就減少我們相關(guān)計(jì)算量。所以給機(jī)器人引入目標(biāo)和策略的概念是有必要的。引入目標(biāo)和策略的方式非常多,下面簡(jiǎn)單的介紹一種。
?
首先將機(jī)器人狀態(tài)分為:無(wú)目標(biāo)狀態(tài),有目標(biāo)狀態(tài)。
確定目標(biāo)總類:大對(duì)子,清一色, 暗七對(duì),青七對(duì),只摸叫牌等。
無(wú)目標(biāo)情況:按常規(guī)計(jì)算出牌。
有目標(biāo)情況:根據(jù)目標(biāo)進(jìn)行不同的權(quán)值計(jì)算。
目標(biāo)轉(zhuǎn)換操作和條件:確定目標(biāo),執(zhí)行目標(biāo),更改目標(biāo),以及對(duì)應(yīng)的條件。
這些操作需要依賴其他因素,如麻將比賽前期,中期,后期,當(dāng)前是否聽牌等。
最后確定每個(gè)目標(biāo)對(duì)應(yīng)權(quán)值計(jì)算帶來(lái)的影響。
?
例:
1.如果機(jī)器人確定了清一色,那么其他的花色牌就不用考慮了。
2.如果機(jī)器人下叫后權(quán)值很多決定不換叫,那么剩下的就只摸叫牌。
?
策略和目標(biāo)的引入不屬于麻將算法的一部分,但是屬于一個(gè)強(qiáng)大機(jī)器人的一部分。 所以這兩部分可以分開實(shí)現(xiàn)。即在麻將算法的基礎(chǔ)上加入目標(biāo)和策略系統(tǒng)。
5.????? 機(jī)器人等級(jí)劃分
可以講機(jī)器人設(shè)置為1-10級(jí),0級(jí)機(jī)器人直接出最后一張。
1級(jí)機(jī)器人:基礎(chǔ)權(quán)值
2級(jí)機(jī)器人:基礎(chǔ)權(quán)值+牌張數(shù)加成
3級(jí)機(jī)器人:基礎(chǔ)權(quán)值+牌張數(shù)加成+杠牌風(fēng)險(xiǎn)
4級(jí)機(jī)器人:基礎(chǔ)權(quán)值+牌張數(shù)加成+杠牌風(fēng)險(xiǎn)+炮牌風(fēng)險(xiǎn)
5級(jí)機(jī)器人:基礎(chǔ)權(quán)值+牌張數(shù)加成+杠牌風(fēng)險(xiǎn)+炮牌風(fēng)險(xiǎn)+胡牌風(fēng)險(xiǎn)
6級(jí)機(jī)器人:5級(jí)機(jī)器人+透視
7級(jí)機(jī)器人:5級(jí)機(jī)器人+透視+20%廢牌更換率
8級(jí)機(jī)器人:5級(jí)機(jī)器人+透視+20%廢牌更換率+20%叫牌獲取率
9級(jí)機(jī)器人:5級(jí)機(jī)器人+透視+40%廢牌更換率+20%叫牌獲取率
10級(jí)機(jī)器人:5級(jí)機(jī)器人+透視+40%廢牌更換率+20%叫牌獲取率+20%起手大牌獲取率
?
說(shuō)明:
1-5級(jí)不含服務(wù)器作弊
6-10級(jí)含服務(wù)器作弊
透視:即服務(wù)器讓機(jī)器人知道所有玩家牌。
廢牌更換率:即服務(wù)器按一定的概率更換玩家獲取的廢牌,即玩家缺的牌。
叫牌獲取率:即服務(wù)器按一定的概率給玩家之間發(fā)叫牌。
起手打牌獲取率:即服務(wù)器按一定概率起手發(fā)牌是給機(jī)器人大牌,如清一色,大對(duì)子等。
?
?
轉(zhuǎn)載于:https://my.oschina.net/u/1024573/blog/647259
總結(jié)
- 上一篇: 【知识图谱】构建红楼梦知识图谱
- 下一篇: 单片机之LED闪烁