鬥地主AI演算法 第八章 被動出牌 2

2021-09-18 07:38:43 字數 4711 閱讀 3680

上一章我們已經搭好了被動出牌的基本架子,本章我們主要說明一下被動出牌演算法的基本步驟。

我把出牌邏輯分為四個階段,也就是策略的優先順序。分別是:【直接打光手牌】→【同型別牌壓制】→【炸彈王炸壓制】→【不出】

第一階段【直接打光手牌】就是說如果我們可以一次性把手牌打出,那就不用考慮接下來價值之類的問題了,因為已經贏了。這種情況可能是對方打出的牌型和你一樣且你比他大,或者你剩的牌是炸彈王炸。

我們先以單牌為例:

//剪枝:如果能出去最後一手牌直接出

cardgroupdata surcardgroupdata = ins_surcardstype(clshandcarddata.value_ahandcardlist);

if (surcardgroupdata.cgtype != cgerror)

else

if (surcardgroupdata.cgtype == cgbomb_card|| surcardgroupdata.cgtype == cgking_card)

}

也就是通過呼叫第六章實現的判定是否為一手牌函式,如果返回的型別與當前牌型相同且nmaxcard值更大一些,或者是炸彈王炸。那麼直接打光所有手牌。

put_all_surcards打光所有手牌實現方法:

/*封裝好的 將所有的牌都打出*/

void

put_all_surcards

(gamesituation &clsgamesituation, handcarddata &clshandcarddata, cardgroupdata surcardgroupdata)

void

put_all_surcards

( handcarddata &clshandcarddata, cardgroupdata surcardgroupdata)

第二階段【同型別牌壓制】就是需要遍歷當前手牌滿足可以管上的組合,然後選出最優解。我們先做一些準備工作,因為要考慮出牌和不出牌收益情況,所以我們先計算出當前手牌的價值,之所以把原始牌型輪數+1也是為了在這裡若能搶占一輪盡量出牌管上。當然,若管完之後的剩餘價值損失的太大就只能算了。

還需要設定暫存最佳牌號的變數、是否出牌的標誌。

//暫存最佳的價值

handcardvalue besthandcardvalue = get_handcardvalue(clshandcarddata);

//我們認為不出牌的話會讓對手乙個輪次,即加一輪(權值減少7)便於後續的對比參考。

besthandcardvalue.needround +=

1;//暫存最佳的牌號

int bestmaxcard=

0;//是否出牌的標誌

bool putcards =

false;

然後就是迴圈遍歷滿足條件的若干個選擇,選出最優的解決方案。還是以單牌為例:

for (

int i = clsgamesituation.uctnowcardgroup.nmaxcard +

1; i <

18; i++)}}

if (putcards)

按照之前價值的定義,我們對比的公式為總價值-輪數*7。

第三階段【炸彈王炸壓制】的策略與上文邏輯類似,唯一的區別就是加了乙個手牌剩餘價值的判定,就是如果我出完炸剩餘手牌價值還蠻可觀的話,我們就可以任性的炸出,

畢竟此時我們獲勝的機率很大。

for (

int i =

3; i <

16; i++)}}

if (putcards)

//王炸

if (clshandcarddata.value_ahandcardlist[

17] >

0 && clshandcarddata.value_ahandcardlist[

16] > 0)}

若以上三個階段都沒有return的話,就進入我們第四階段了。

第四階段【不出】

//管不上

clshandcarddata.uctputcardtype = get_groupdata(cgzero,

0, 0);

return;

這也就是我們被動出牌演算法的基本步驟,本章是以單牌為例,後續文章會進而補充其他的牌型。

上一章我們已經搭好了被動出牌的基本架子,本章我們主要說明一下被動出牌演算法的基本步驟。

我把出牌邏輯分為四個階段,也就是策略的優先順序。分別是:【直接打光手牌】→【同型別牌壓制】→【炸彈王炸壓制】→【不出】

第一階段【直接打光手牌】就是說如果我們可以一次性把手牌打出,那就不用考慮接下來價值之類的問題了,因為已經贏了。這種情況可能是對方打出的牌型和你一樣且你比他大,或者你剩的牌是炸彈王炸。

我們先以單牌為例:

//剪枝:如果能出去最後一手牌直接出

cardgroupdata surcardgroupdata = ins_surcardstype(clshandcarddata.value_ahandcardlist);

if (surcardgroupdata.cgtype != cgerror)

else

if (surcardgroupdata.cgtype == cgbomb_card|| surcardgroupdata.cgtype == cgking_card)

}

也就是通過呼叫第六章實現的判定是否為一手牌函式,如果返回的型別與當前牌型相同且nmaxcard值更大一些,或者是炸彈王炸。那麼直接打光所有手牌。

put_all_surcards打光所有手牌實現方法:

/*封裝好的 將所有的牌都打出*/

void

put_all_surcards

(gamesituation &clsgamesituation, handcarddata &clshandcarddata, cardgroupdata surcardgroupdata)

void

put_all_surcards

( handcarddata &clshandcarddata, cardgroupdata surcardgroupdata)

第二階段【同型別牌壓制】就是需要遍歷當前手牌滿足可以管上的組合,然後選出最優解。我們先做一些準備工作,因為要考慮出牌和不出牌收益情況,所以我們先計算出當前手牌的價值,之所以把原始牌型輪數+1也是為了在這裡若能搶占一輪盡量出牌管上。當然,若管完之後的剩餘價值損失的太大就只能算了。

還需要設定暫存最佳牌號的變數、是否出牌的標誌。

//暫存最佳的價值

handcardvalue besthandcardvalue = get_handcardvalue(clshandcarddata);

//我們認為不出牌的話會讓對手乙個輪次,即加一輪(權值減少7)便於後續的對比參考。

besthandcardvalue.needround +=

1;//暫存最佳的牌號

int bestmaxcard=

0;//是否出牌的標誌

bool putcards =

false;

然後就是迴圈遍歷滿足條件的若干個選擇,選出最優的解決方案。還是以單牌為例:

for (

int i = clsgamesituation.uctnowcardgroup.nmaxcard +

1; i <

18; i++)}}

if (putcards)

按照之前價值的定義,我們對比的公式為總價值-輪數*7。

第三階段【炸彈王炸壓制】的策略與上文邏輯類似,唯一的區別就是加了乙個手牌剩餘價值的判定,就是如果我出完炸剩餘手牌價值還蠻可觀的話,我們就可以任性的炸出,

畢竟此時我們獲勝的機率很大。

for (

int i =

3; i <

16; i++)}}

if (putcards)

//王炸

if (clshandcarddata.value_ahandcardlist[

17] >

0 && clshandcarddata.value_ahandcardlist[

16] > 0)}

若以上三個階段都沒有return的話,就進入我們第四階段了。

第四階段【不出】

//管不上

clshandcarddata.uctputcardtype = get_groupdata(cgzero,

0, 0);

return;

這也就是我們被動出牌演算法的基本步驟,本章是以單牌為例,後續文章會進而補充其他的牌型。

鬥地主AI演算法 第八章 被動出牌 2

上一章我們已經搭好了被動出牌的基本架子,本章我們主要說明一下被動出牌演算法的基本步驟。我把出牌邏輯分為四個階段,也就是策略的優先順序。分別是 直接打光手牌 同型別牌壓制 炸彈王炸壓制 不出 第一階段 直接打光手牌 就是說如果我們可以一次性把手牌打出,那就不用考慮接下來價值之類的問題了,因為已經贏了。...

鬥地主AI演算法 第七章 被動出牌 1

哎,之前扯了那麼多蛋,終於講出牌了!本章開始講被動出牌的邏輯演算法。首先我們先把架子搭起來,被動出牌我們肯定是要知道場上目前打出的是什麼牌型。在第二章資料結構裡我們定義過,遊戲全域性類裡面有乙個存放當前牌型結構的成員,即 當前打出牌的型別資料,被動出牌時玩家根據這裡做出篩選 cardgroupdat...

鬥地主AI演算法 第七章 被動出牌 1

哎,之前扯了那麼多蛋,終於講出牌了!本章開始講被動出牌的邏輯演算法。首先我們先把架子搭起來,被動出牌我們肯定是要知道場上目前打出的是什麼牌型。在第二章資料結構裡我們定義過,遊戲全域性類裡面有乙個存放當前牌型結構的成員,即 當前打出牌的型別資料,被動出牌時玩家根據這裡做出篩選 cardgroupdat...