第一章业务逻辑结尾部分我提到了权值的计算方法:

①每个单牌都有一个基础价值②组合牌型的整体价值与这个基础价值有关,但显然计算规则不完全一样。③整手牌可以分成若干个组合牌,但分法不唯一。

当时,我说了①和②可以直接定义,③需要迭代计算。所以本章的主要内容就是确定基础价值&组合牌型的价值定义

对于牌型权值的定义看似简单,实际却需要大量的推敲。这就跟游戏里不同英雄属性、技能反复修改一样。事实上,直至整个工程开发完毕,我还在修改权值定义,因为这是唯一影响逻辑处理的因素。如果你觉得程序返回的出牌策略不太符合你的想法,那么一定是权值定义这里出现的问题。

首先,网络上有很多文章统计出不同牌型出现的概率,但是我始终觉得,对于斗地主而言,一种牌型出现的概率并不是那么重要,举个例子。我认为33和3的价值是一样的。

因为大多数情况你出了都会被管,若你有飞机,这两者都可以被带出。或许从概率的角度来说能管上33的牌会更少,但事实上,对方究竟管不管你,用什么管你取决于对方的牌型组合。你出33,对方可以出44,但是你出3,对方不一定会出4管你,因为这样他还会剩下一个4,他会用其他的牌管你,并且,若该牌型很难出现,即被管的可能性很低,那么他管上别人的可能性也很低。所以实际上这种牌型的收益可以近似的等于不存在。况且我也不想搞一套很复杂的公式,我的想法是用一些简单的公式得出一个中肯的价值,或许不是那么的公平,但至少程序应对绝大部分局面都能给出比较正确的操作。

首先,我们有出牌轮次的定义,我们尽量使得出牌轮次少一些,还是那句话,所以对于牌型,大家是公平的,你组成这种牌型的几率低,但你管别人的几率也低。你若想出去,还是要用其他的牌抢占先手再打出,所以这种牌型不会给你带来抢占出牌权的收益。那么他的好处或许是能让你快速的出完牌,减少出牌轮次。

然后就是牌的基础价值定义,牌的价值一定有正有负,我也是经过一些测试及计算,确定了价值为0的位置是10。

我们有15种牌型,从值域来说是3~17。那么10属于最中间的位置,还有就是我们经常管10以上的牌称作带“人”的牌(因为JQK有人图案)。我们认为带“人”的牌都是干部,是可以管别人的。

或许有人会说,王比其他牌型少,且人家若成了王炸又不可能拆开出。但实际玩牌的时候王牌管单出现的几率和其他牌差不多,因为其他牌也需要考虑是否组成对牌、三牌、顺子等情况。大家的拆分选择可以认为近似公平的。至于牌少的问题,你想想你一局游戏实际打单牌的次数也没多少次。况且,基础价值是应用于所有类型的牌值的。但他不能说明一切问题。他只是表示当你的牌值大于10以上,你管上别人的概率高,反之,你被管的概率高。

根据这个思路,我们暂定单双三等牌型的价值就是这个基础价值。也就是3的基础价值是-7  大王的基础价值是7

根据这个基础价值,我们便得出控手(轮次)的价值。因为最大负牌值是-7,所以控手价值是7,这个应该不难理解把。因为你若想打出一个3,你就必须得抢占一次控手机会。然后再打出3。同理,一次控手机会可以出一手牌,所以单个轮次的价值也是7,若你的牌型组合价值大于7,则认为你这种牌型可以创造一个轮次,举个简单的例子 王炸。

接下来是顺子的定义。顺子权值的思路我也犹豫了好久,最后决定是其最大牌的单体价值+1,因为2不参与顺子。至于王就不考虑了。原来考虑到是否要采用平均值等,后来发现顺子到底能否被管以及管别人,主要决定于最大的牌,比如说你从3~A和从10~A是一样的。管别人的话也不是越长越好,你长顺子强行管短顺子可能还会多出很多单牌。

对于四带二、飞机等定义,是修改最多的。的确这样的牌很难被管,所以我给了他一个非负价值,但是又发现其价值很大,比如说KKKQQQJJJ他的价值已经飙到11了。

那么程序给出的策略就是 分开打,因为KKKQQQ也是飞机。一个轮次的价值是7,远小于11。所以可以拆成两个轮次。鉴于这一点,我把价值调成为非负且除以2

这样这类牌型的价值永远不会大于7,毕竟这种牌型能一手出完不能分成两手出。而且根据之前的逻辑,你很难被管所以你也很难管别人,那么正价值收益缩减也是很自然的了。

最后说一下炸弹及王炸,炸弹无负价值且+一个轮次7,因为我们认为炸弹大概率能抢占一局轮次。而炸弹及王炸没有正价值收益缩减的原因是处于信仰把,尽量的不要拆分。也符合我们人性。我们都是把炸弹、王炸看成最重要的。

还有,在此之前我有想过权值定义取不拆分和拆分的最大价值。比如说3A带俩2,那么其实俩2的价值也很高,后期很有可能拆开打。但是最后因为引入了手牌轮次参数,所以不考虑拆分价值了。不然四带二的价值爆炸。

下面给出目前暂定的定义方案

/*评分逻辑思维:0.由于新策略引入手牌轮次参数,所以不再考虑拆分价值。
1.牌力基础价值:我们认为10属于中等位置,即<10单牌价值为负,大于10的单牌价值为正
2.控手的价值定义:我们认为一次控手权可以抵消一次手中最小牌型,最小牌型(3)的价值为-7,即我们定义一次控手权的价值为7
3.单牌的价值定义:该牌的基础价值
4.对牌的价值定义:我们认为对牌与单牌价值相等(均可以被三牌带出)故其价值为该牌的基础价值
5.三牌的价值定义:三不带:     该牌的基础价值三带一:     我们认为通常带出去的牌价值一定无正价值故其价值为该牌的基础价值三带二:     我们认为通常带出去的牌价值一定无正价值故其价值为该牌的基础价值
6.四牌的价值定义:炸弹:       我们认为炸弹会享有一次控手权利且炸弹被管的概率极小,故其无负价值,非负基础价值+7四带二单:   我们认为四带二单管人与被管的概率极小,故其无负价值,其价值为非负基础价值/2(该值最大为6小于一个轮次7)四带二对:   我们认为四带二对管人与被管的概率极小,故其无负价值,其价值为非负基础价值/2(该值最大为6小于一个轮次7)
7.王炸的价值定义:已知炸2价值为15-3+7=19分,故王炸价值为20分。
8.顺子的价值定义:单顺:       我们认为单顺的价值等于其最大牌的单体价值,且2不参与顺子,故顺子的权值依次提升1双顺:       我们认为双顺的价值等于其最大牌的单体价值,且2不参与顺子,故顺子的权值依次提升1飞机不带:   由于飞机牌型管人与被管的概率极小,故其无负价值,其价值为非负基础价值/2(该值最大为6小于一个轮次7)飞机带双翅: 由于飞机牌型管人与被管的概率极小,故其无负价值,其价值为非负基础价值/2(该值最大为6小于一个轮次7)飞机带单翅: 由于飞机牌型管人与被管的概率极小,故其无负价值,其价值为非负基础价值/2(该值最大为6小于一个轮次7)
9.根据数值分布,我们暂定:   <10不叫分,10-14叫一分,15-19叫两分,20以上叫三分PS.以上逻辑纯属扯淡,谁信谁SB。。。。。
*/

以及封装好的获取价值函数

/*封装好的获取各类牌型组合结构函数CardGroupType cgType:牌型
int MaxCard:决定大小的牌值
int Count:牌数返回值:CardGroupData
*/
CardGroupData get_GroupData(CardGroupType cgType, int MaxCard, int Count)
{CardGroupData uctCardGroupData;uctCardGroupData.cgType = cgType;uctCardGroupData.nCount = Count;uctCardGroupData.nMaxCard = MaxCard;//不出牌型if (cgType == cgZERO)uctCardGroupData.nValue = 0;//单牌类型else if (cgType == cgSINGLE)uctCardGroupData.nValue = MaxCard - 10;//对牌类型else if (cgType == cgDOUBLE)uctCardGroupData.nValue = MaxCard - 10;//三条类型else if (cgType == cgTHREE)uctCardGroupData.nValue = MaxCard - 10;//单连类型else if (cgType == cgSINGLE_LINE)uctCardGroupData.nValue = MaxCard - 10 + 1;//对连类型else if (cgType == cgDOUBLE_LINE)uctCardGroupData.nValue = MaxCard - 10 + 1;//三连类型else if (cgType == cgTHREE_LINE)uctCardGroupData.nValue = (MaxCard - 3 + 1)/2;//三带一单else if (cgType == cgTHREE_TAKE_ONE)uctCardGroupData.nValue = MaxCard - 10;//三带一对else if (cgType == cgTHREE_TAKE_TWO)uctCardGroupData.nValue = MaxCard - 10;//三带一单连else if (cgType == cgTHREE_TAKE_ONE_LINE)uctCardGroupData.nValue = (MaxCard - 3 + 1) / 2;//三带一对连else if (cgType == cgTHREE_TAKE_TWO_LINE)uctCardGroupData.nValue = (MaxCard - 3 + 1) / 2;//四带两单else if (cgType == cgFOUR_TAKE_ONE)uctCardGroupData.nValue = (MaxCard - 3 ) / 2;//四带两对else if (cgType == cgFOUR_TAKE_TWO)uctCardGroupData.nValue = (MaxCard - 3 ) / 2;//炸弹类型 else if (cgType == cgBOMB_CARD)uctCardGroupData.nValue = MaxCard - 3 + 7;//王炸类型 else if (cgType == cgKING_CARD)uctCardGroupData.nValue = 20;//错误牌型elseuctCardGroupData.nValue = 0;return uctCardGroupData;
}

注意!!!以上价值定义是作者本人主观意愿,并非斗地主游戏最佳策略,请大家遵从自己的内心适当修改~~

好了,权值定义做完后,我们便可以实现比较重要的一个模块了,即手牌总价值计算函数,也就是我一直说的F()算法函数。

敬请关注下一章:斗地主AI算法——第五章の总值计算

斗地主AI算法——第四章の权值定义相关推荐

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

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

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

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

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

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

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

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

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

    哎,之前扯了那么多蛋,终于讲出牌了! 本章开始讲被动出牌的逻辑算法.首先我们先把架子搭起来,被动出牌我们肯定是要知道场上目前打出的是什么牌型. 在第二章数据结构里我们定义过,游戏全局类里面有一个存放当 ...

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

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

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

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

  8. 斗地主AI算法——第二章の数据结构

    上一章我们已经确立了基本的业务逻辑处理流程.从本章开始,我们便进入开发阶段. 首先就是明确我们都需要哪些数据,且它们以怎样的形式存储. 首先从上一章反复提到的手牌权值结构说起,也就是F()的返回值,他 ...

  9. 斗地主AI算法——第十六章の样例分析

    上一章,我们已经完成了测试模块的开发.至此我们已经可以进行整体测试了.本章主要内容就是对随机生成的对局情况进行简单的分析. 实际上整个开发过程绝大部分时间都是用在样例分析上,通过样例给出的返回操作分析 ...

最新文章

  1. linux文件操作函数程序,linux 文件操作函数
  2. ansible role中常代码块
  3. 【转】系统管理类DOS命令汇总
  4. Linux使用vsftpd搭建FTP服务
  5. 如何建立数据驱动文化
  6. CVPR2020 | 参数量减半,北大开源全新高效空域转换模块,还原图像逼真细节
  7. 1777亿重罚,苹果瑟瑟发抖!
  8. Python标准库shutil中rmtree()使用回调函数
  9. 卷积、卷积矩阵(Convolution matrix)与核(Kernel)
  10. python和java的区别-三分钟看懂Python和Java的区别
  11. php木马检测关键词
  12. python怎么更新sp2_GitHub - Sp2-Hybrid/Python-100-Days: Python - 100天从新手到大师
  13. download 下载文件 IE兼容性处理
  14. 小程序源码:游戏助手王者战力查询扫码登录多功能微信小程序
  15. NDK Resolution Outcome: Project settings: Gradle model version=XXX, NDK version is UNKNOWN
  16. matlab 多项式相减,matlab多项式计算与数据处理
  17. 人工智能-深度学习-yolov3口罩佩戴识别
  18. InterValue正式启动主网映射
  19. Linux下service mysqld start 启动MySQL提示Redirecting to /bin/systemctl start mysqld.servic
  20. 游戏编程之四 diectxdarw基础篇

热门文章

  1. java内存shell_Springboot 内存shell
  2. 96KB存储器的怎么算地址范围_产品条码怎么申请费用
  3. ubuntu16.04中如何将python3设置为默认
  4. [Pytorch] BCELoss和BCEWithLogitsLoss(Sigmoid-BCELoss合成为一步)
  5. TypeScript环境搭建
  6. async js 返回值_获取JavaScript异步函数的返回值
  7. Excel 批量处理行高(图文教程) - Excel篇
  8. link标签引入.css文件(目的):适配不同屏幕
  9. 关于MongoDB数据库的可连接性稳定性 - 抛转篇
  10. phpcmsV9留言插件提交后返回上一页实现方法