哎,之前扯了那么多蛋,终于讲出牌了!

本章开始讲被动出牌的逻辑算法。首先我们先把架子搭起来,被动出牌我们肯定是要知道场上目前打出的是什么牌型。

在第二章数据结构里我们定义过,游戏全局类里面有一个存放当前牌型结构的成员,即

 //当前打出牌的类型数据,被动出牌时玩家根据这里做出筛选CardGroupData uctNowCardGroup;

我们即将通过他进行类型的筛选,所以肯定是要枚举各类牌型的,也就是这个样子的。

是的不要质疑!就是这个样子的~~

当然了,虽然是2.0初级版,我们还是要给予一定的灵性的,比如说当最后只剩两手牌且存在王炸的话,王炸优先出。

 /*王炸——当前策略只处理王炸作为倒数第二手的优先出牌逻辑,后续版本会在此基础上优化*/if (clsHandCardData.value_aHandCardList[17] > 0 && clsHandCardData.value_aHandCardList[16] > 0){clsHandCardData.value_aHandCardList[17] --;clsHandCardData.value_aHandCardList[16] --;clsHandCardData.nHandCardCount -= 2;HandCardValue tmpHandCardValue = get_HandCardValue(clsHandCardData);clsHandCardData.value_aHandCardList[16] ++;clsHandCardData.value_aHandCardList[17] ++;clsHandCardData.nHandCardCount += 2;if (tmpHandCardValue.NeedRound == 1){clsHandCardData.value_nPutCardList.push_back(17);clsHandCardData.value_nPutCardList.push_back(16);clsHandCardData.uctPutCardType = clsGameSituation.uctNowCardGroup = get_GroupData(cgKING_CARD, 17, 2);return;}}

算法思路:若存在手牌17(大王)和16(小王),那么先去除这两张牌

然后通过get_HandCardValue获取剩余轮次。

再回溯到原有状态。若只剩一手,则打出王炸。

出牌的操作也很简单,将需要打出的牌进入clsHandCardData.value_nPutCardList数组,且通过第四章提到的get_GroupData函数获取类型结构再赋值给手牌类以及游戏全局类相应的成员变量。当确定好出牌策略后,直接return。因为被动出牌的分支只会走一个,为了节约时间,所以每个分支里都有return,若没有走入任何分支则视为错误数据。

我们先把最简单的类型写出来,就是别人出王炸时的策略。

 //王炸类型 人都王炸了你还出个毛else if (clsGameSituation.uctNowCardGroup.cgType == cgKING_CARD){clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}

怎么样,是不是很简单?

若不出牌,我们只更新自己手牌类型就好了。若出牌时,不但要更新自己手牌信息,也要更新游戏全局类里面的当前出牌信息。不过我更推荐后期嵌入的时候通过服务器来获取当前出牌的信息。比如我的测试函数里会加上:

     if (arrHandCardData[indexID].uctPutCardType.cgType != cgZERO){clsGameSituation.nCardDroit = indexID;clsGameSituation.uctNowCardGroup = arrHandCardData[indexID].uctPutCardType;}

另外,出牌前记得清空一下出牌序列,就是在一开始加:

clsHandCardData.ClearPutCardList();

所以,整个函数的架子是这样的,假设我们啥都管不上。

/*
2.0版本策略  根据场上形势决定当前预打出的手牌——被动出牌
*/
void get_PutCardList_2_limit(GameSituation &clsGameSituation, HandCardData &clsHandCardData)
{clsHandCardData.ClearPutCardList();/*王炸——当前策略只处理王炸作为倒数第二手的优先出牌逻辑,后续版本会在此基础上优化*/if (clsHandCardData.value_aHandCardList[17] > 0 && clsHandCardData.value_aHandCardList[16] > 0){clsHandCardData.value_aHandCardList[17] --;clsHandCardData.value_aHandCardList[16] --;clsHandCardData.nHandCardCount -= 2;HandCardValue tmpHandCardValue = get_HandCardValue(clsHandCardData);clsHandCardData.value_aHandCardList[16] ++;clsHandCardData.value_aHandCardList[17] ++;clsHandCardData.nHandCardCount += 2;if (tmpHandCardValue.NeedRound == 1){clsHandCardData.value_nPutCardList.push_back(17);clsHandCardData.value_nPutCardList.push_back(16);clsHandCardData.uctPutCardType = clsGameSituation.uctNowCardGroup = get_GroupData(cgKING_CARD, 17, 2);return;}}//错误牌型  不出if (clsGameSituation.uctNowCardGroup.cgType == cgERROR){clsHandCardData.uctPutCardType = get_GroupData(cgERROR, 0, 0);return;}//不出牌型,在被动出牌策略里也是错误数据 不出else if (clsGameSituation.uctNowCardGroup.cgType == cgZERO){clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//单牌类型else if (clsGameSituation.uctNowCardGroup.cgType == cgSINGLE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//对牌类型else if (clsGameSituation.uctNowCardGroup.cgType == cgDOUBLE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//三牌类型else if (clsGameSituation.uctNowCardGroup.cgType == cgTHREE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//单连类型else if (clsGameSituation.uctNowCardGroup.cgType == cgSINGLE_LINE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//对连类型else if (clsGameSituation.uctNowCardGroup.cgType == cgDOUBLE_LINE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//三连类型else if (clsGameSituation.uctNowCardGroup.cgType == cgTHREE_LINE){   //管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//三带一单else if (clsGameSituation.uctNowCardGroup.cgType == cgTHREE_TAKE_ONE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//三带一对else if (clsGameSituation.uctNowCardGroup.cgType == cgTHREE_TAKE_TWO){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//三带一单连else if (clsGameSituation.uctNowCardGroup.cgType == cgTHREE_TAKE_ONE_LINE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//三带一对连else if (clsGameSituation.uctNowCardGroup.cgType == cgTHREE_TAKE_TWO_LINE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//四带两单else if (clsGameSituation.uctNowCardGroup.cgType == cgFOUR_TAKE_ONE){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//四带两对else if (clsGameSituation.uctNowCardGroup.cgType == cgFOUR_TAKE_TWO){//管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//炸弹类型 else if (clsGameSituation.uctNowCardGroup.cgType == cgBOMB_CARD){   //管不上clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;  }//王炸类型 人都王炸了你还出个毛else if (clsGameSituation.uctNowCardGroup.cgType == cgKING_CARD){clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);return;}//异常处理 不出else{clsHandCardData.uctPutCardType = get_GroupData(cgZERO, 0, 0);}return;
}

当然,啥都管不上肯定是不行的,所以接下来我们会填充各种牌型的策略算法。

敬请关注下一章:斗地主AI算法——第八章の被动出牌(2)

斗地主AI算法——第七章の被动出牌(1)相关推荐

  1. 斗地主AI算法——第十一章の被动出牌(5)

    本章是被动出牌的最后一章,截止目前,我们已经解决了大部分牌型.只剩下飞机和炸弹了. 飞机无疑是最复杂的类型,他等于顺子和三带的结合体,但又增加了很多难度. 根据上一章的算法,我们可以大概想到,若是带出 ...

  2. 斗地主AI算法——第十三章の主动出牌(2)

    上一章我们已经搭好了出牌算法的基本框架,本章主要实现优先处理的三带.飞机等牌型. 首先定义一些基本变量: //暂存最佳的价值HandCardValue BestHandCardValue;BestHa ...

  3. 斗地主AI算法——第六章の牌型判断

    本章实现了上一章提到的检查当前是否只是一手牌函数ins_SurCardsType /* 检查剩余的牌是否只是一手牌是: 返回手牌类型数据 不是:返回错误类型(cgERROR) */ CardGroup ...

  4. 斗地主AI算法——第四章の权值定义

    第一章业务逻辑结尾部分我提到了权值的计算方法: ①每个单牌都有一个基础价值②组合牌型的整体价值与这个基础价值有关,但显然计算规则不完全一样.③整手牌可以分成若干个组合牌,但分法不唯一. 当时,我说了① ...

  5. 斗地主AI算法——第三章の数据处理

    上一章我们定义了基本的数据结构,相信大家看到手牌类里面那么多出牌序列时一定会比较愤慨... 其实一开始写的时候我也是觉得很脑残,不过后续开发证明了这样的结构还是可以的,因为只要我封装了一层数据转换,接 ...

  6. 斗地主AI算法——第九章の被动出牌(3)

    上一章已经说明了被动出牌算法基本的出牌思路,且以单牌为例给出了具体的代码. 对牌.三不带牌型实现方法与单牌基本类似.改动的地方主要是枚举牌类型,出牌时value_nPutCardList的处理,回溯时 ...

  7. 斗地主AI算法——第十七章の总结整理

    转载请标明出处:https://blog.csdn.net/sm9sun/article/details/70878001  文章出自:九日王朝 查看全文 http://www.taodudu.cc/ ...

  8. 斗地主AI算法——第十章の被动出牌(4)

    上一章已经说明了单顺的实现方法,双顺.三不带顺牌型实现方法与单牌基本类似.改动的地方除了上一章说的枚举牌类型,出牌时value_nPutCardList的处理,回溯时value_aHandCardLi ...

  9. 斗地主AI算法——第十二章の主动出牌(1)

    本章开始,我们介绍主动出牌的算法,和被动出牌类似,我们第一步把主要架子搭起来. 首先清空出牌序列 clsHandCardData.ClearPutCardList(); 主动出牌的策略按照优先级大体可 ...

最新文章

  1. 从ViewDragLayout中学到的一些事实
  2. 3.Factory Method 工厂方法模式(创建型模式)
  3. HashMap源代码深入剖析
  4. iview组件库 - 穿梭栏设置
  5. springbboot加密打包_Spring Boot 配置 Security 密码加密
  6. 怎么样写一个 node.js模块以及NPM Package
  7. sony lt26i android 5.1rom,索尼 LT26 Xperia L 5.1.1 ROM刷机包 扁平化 来电归属 农历 新相机 稳定流畅...
  8. 如何用代码编写四则运算?
  9. 三维重建开源项目汇总
  10. 海康8700联网网关如何通过GB28181接入安防摄像头互联网直播流媒体解决方案EasyGBS实现web端无插件直播
  11. Python--图片转字符画
  12. cad卸载_解决CAD小白入门的第一个难题,三招任你选
  13. 彻底解决Ubuntu18.04搜狗拼音输入法问题---支持Pycharm、WPS
  14. 检索报告计算机类,计算机检索报告.docx
  15. iphone之Info.plist的属性
  16. 《逆袭进大厂》第十二弹之MySQL重点篇27问27答
  17. php公众号用户关注,微信公众号获取用户信息(用户关注公众号)
  18. 航芯技术分享 | 一文读懂什么是量子密码
  19. 用Dynamips构建能够与真实机器通信的IPSec ***环境
  20. 删除“打开方式”里的其他程序

热门文章

  1. 9 PP配置-生产主数据-工作中心相关-定义工序控制码
  2. 44 MM配置-采购-条件-定价过程-定义条件类型
  3. 高级语言中的关键字:const用法分析
  4. python调用函数_Python 函数中的 4 种参数类型
  5. linux内核那些事之early boot memory-memblock
  6. jquery-选择器
  7. [流体输配管网]古罗马渡槽从水源到城市的落差估计
  8. java 查询windows进程_Oracle查询语句,你知道几个?(下)
  9. 插件设置修改失败_【王者荣耀金牌特权】详细技术设置教程,更新异常解决办法...
  10. Ubuntu系统截图