棋牌游戏开发:斗地主AI之被动出牌(8.2)

查看斗地主代码全部文章点击这里:棋牌游戏开发:斗地主AI系列

然后就是循环遍历满足条件的若干个选择,选出最优的解决方案。

还是以单牌为例:

    for (int i = clsGameSituation.uctNowCardGroup.nMaxCard + 1; i < 18; i++)

    {

    if (clsHandCardData.value_aHandCardList[i] > 0)

    {

    //尝试打出一张牌,估算剩余手牌价值

    clsHandCardData.value_aHandCardList[i]--;

    clsHandCardData.nHandCardCount--;

    HandCardValue tmpHandCardValue=get_HandCardValue(clsHandCardData);

    clsHandCardData.value_aHandCardList[i]++;

    clsHandCardData.nHandCardCount++;

    //选取总权值-轮次*7值最高的策略  因为我们认为剩余的手牌需要n次控手的机会才能出完,若轮次牌型很大(如炸弹) 则其-7的价值也会为正

    if ((BestHandCardValue.SumValue-(BestHandCardValue.NeedRound*7)) <= (tmpHandCardValue.SumValue-(tmpHandCardValue.NeedRound*7)))

    {

    BestHandCardValue = tmpHandCardValue;

    BestMaxCard = i;

    PutCards = true;

    }

    }

    }

    if (PutCards)

    {

    clsHandCardData.value_nPutCardList.push_back(BestMaxCard);

    clsHandCardData.uctPutCardType = clsGameSituation.uctNowCardGroup = get_GroupData(cgSINGLE, BestMaxCard, 1);

    return;

    }

按照之前价值的定义,我们对比的公式为总价值-轮数*7。

第三阶段【炸弹王炸压制】的策略与上文逻辑类似,唯一的区别就是加了一个手牌剩余价值的判定,就是如果我出完炸剩余手牌价值还蛮可观的话,我们就可以任性的炸出,

毕竟此时我们获胜的几率很大。

for (int i = 3; i < 16; i++)

    {

    if (clsHandCardData.value_aHandCardList[i] == 4)

    {

    //尝试打出炸弹,估算剩余手牌价值,因为炸弹可以参与顺子,不能因为影响顺子而任意出炸

    clsHandCardData.value_aHandCardList[i] -= 4;

    clsHandCardData.nHandCardCount -= 4;

    HandCardValue tmpHandCardValue = get_HandCardValue(clsHandCardData);

    clsHandCardData.value_aHandCardList[i] += 4;

    clsHandCardData.nHandCardCount += 4;

    //选取总权值-轮次*7值最高的策略  因为我们认为剩余的手牌需要n次控手的机会才能出完,若轮次牌型很大(如炸弹) 则其-7的价值也会为正

    if ((BestHandCardValue.SumValue - (BestHandCardValue.NeedRound * 7)) <= (tmpHandCardValue.SumValue - (tmpHandCardValue.NeedRound * 7))

    //如果剩余手牌价值为正,证明出去的几率很大, 那么可以用炸获得先手

    || tmpHandCardValue.SumValue > 0)

    {

    BestHandCardValue = tmpHandCardValue;

    BestMaxCard = i;

    PutCards = true;

    }

    }

    }

    if (PutCards)

    {

    clsHandCardData.value_nPutCardList.push_back(BestMaxCard);

    clsHandCardData.value_nPutCardList.push_back(BestMaxCard);

    clsHandCardData.value_nPutCardList.push_back(BestMaxCard);

    clsHandCardData.value_nPutCardList.push_back(BestMaxCard);

    clsHandCardData.uctPutCardType = clsGameSituation.uctNowCardGroup = get_GroupData(cgBOMB_CARD, BestMaxCard, 4);

    return;

    }

    //王炸

    if (clsHandCardData.value_aHandCardList[17] > 0 && clsHandCardData.value_aHandCardList[16] > 0)

    {

    //如果剩余手牌价值为正,证明出去的几率很大,那么可以用炸获得先手,王炸20分

    if (BestHandCardValue.SumValue > 20)

    {

    clsHandCardData.value_nPutCardList.push_back(17);

    clsHandCardData.value_nPutCardList.push_back(16);

    clsHandCardData.uctPutCardType = clsGameSituation.uctNowCardGroup = get_GroupData(cgKING_CARD, 17, 2);

    return;

    }

    }

若以上三个阶段都没有return的话,就进入我们第四阶段了。

第四阶段【不出】

 //管不上

        clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);

    return;

这也就是我们被动出牌算法的基本步骤,本章是以单牌为例,后续文章会进而补充其他的牌型。

025源码论坛声明 1、本网站中的绝大部分资源来源于网络, 本网站不保证所有资源的正确性和安全性,不为其合法性负责.
2、对于一切使用本网站资源而可能遭致的意外、疏忽、侵权及其造成的损失,本网站对其概不负责,亦不承担任何法律责任。
3、其他单位或个人使用、转载或引用本站原创文章时必须同时征得本025源码网的同意.
4、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时删除并致以最深的歉意。
5、如需要本站的游戏源码或搭建帮助,可以联系站长 15623571666(微信同号)或者扫描右侧二维码!

您可能还会对下面的文章感兴趣:

    cache
    Processed in 0.003137 Second.