斗地主AI算法——第六章の牌型判断
来源:互联网 发布:淘宝上小提琴教学视频 编辑:程序博客网 时间:2024/06/09 19:23
本章实现了上一章提到的检查当前是否只是一手牌函数ins_SurCardsType
/*检查剩余的牌是否只是一手牌是: 返回手牌类型数据不是:返回错误类型(cgERROR)*/CardGroupData ins_SurCardsType(int arr[]);
输入很简单,就是一个状态数组。输出是手牌类型结构
//牌型组合数据结构struct CardGroupData{//枚举类型CardGroupType cgType=cgERROR;//该牌的价值int nValue=0;//含牌的个数int nCount=0;//牌中决定大小的牌值,用于对比int nMaxCard=0;};
首先我们要计算出剩余手牌个数,因为这样便于快速筛选分支。
int nCount = 0;for (int i = 3; i < 18; i++){nCount += arr[i];}CardGroupData retCardGroupData;retCardGroupData.nCount = nCount;
以单牌为例,若该牌型满足单牌,则nCount==1,然后我们再找出那张牌。
//单牌类型if (nCount == 1){//用于验证的变量int prov = 0;int SumValue = 0;for (int i = 3; i < 18; i++){if (arr[i] == 1){SumValue = i - 10;prov++;retCardGroupData.nMaxCard = i;}}if (prov == 1){retCardGroupData.cgType = cgSINGLE;retCardGroupData.nValue= SumValue;return retCardGroupData;}}
对牌,三牌,炸弹同理。
三带一的话需要设置两个验证变量,例如三带一单
if (nCount == 4){//用于验证的变量int prov1 = 0;int prov2 = 0;int SumValue = 0;for (int i = 3; i < 18; i++){if (arr[i] == 3){SumValue = i - 10;prov1++;retCardGroupData.nMaxCard = i;}if (arr[i] == 1){prov2++;}}if (prov1 == 1 && prov2 == 1){retCardGroupData.cgType = cgTHREE_TAKE_ONE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}
三带一对
if (nCount == 5){//用于验证的变量int prov1 = 0;int prov2 = 0;int SumValue = 0;for (int i = 3; i < 16; i++){if (arr[i] == 3){SumValue = i - 10;prov1++;retCardGroupData.nMaxCard = i;}if (arr[i] == 2){prov2++;}}
四带二同理,不过四带二要考虑到带出去的那两张牌型是不是相同
if (nCount == 6){//用于验证的变量int prov1 = 0;int prov2 = 0;int SumValue = 0;for (int i = 3; i < 18; i++){if (arr[i] == 4){SumValue = (i - 3) / 2;prov1++;retCardGroupData.nMaxCard = i;}if (arr[i] == 1|| arr[i] == 2){prov2+= arr[i];}}if (prov1 == 1 && prov2 == 2){retCardGroupData.cgType = cgFOUR_TAKE_ONE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}
判断顺子的话用一个变量记录长度,若当前i值等于0并且之前存在i大于0的情况下,即这个长度就是顺子的长度
例如单连:
if (nCount >= 5){//用于验证的变量int prov = 0;int SumValue = 0;int i;for (i = 3; i < 15; i++){if (arr[i] == 1){prov++;}else{if (prov != 0){break;}}}SumValue = i - 10;if (prov == nCount){retCardGroupData.nMaxCard = i-1;retCardGroupData.cgType = cgSINGLE_LINE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}
王炸就更好判断了,直接判断arr[17]和arr[16]就好了
下面贴出完整代码:
/*检查剩余的牌是否只是一手牌是: 返回手牌类型数据不是:返回错误类型(cgERROR)*/CardGroupData ins_SurCardsType(int arr[]){int nCount = 0;for (int i = 3; i < 18; i++){nCount += arr[i];}CardGroupData retCardGroupData;retCardGroupData.nCount = nCount;//单牌类型if (nCount == 1){//用于验证的变量int prov = 0;int SumValue = 0;for (int i = 3; i < 18; i++){if (arr[i] == 1){SumValue = i - 10;prov++;retCardGroupData.nMaxCard = i;}}if (prov == 1){retCardGroupData.cgType = cgSINGLE;retCardGroupData.nValue= SumValue;return retCardGroupData;}}//对牌类型if (nCount == 2){//用于验证的变量int prov = 0;int SumValue = 0;int i = 0;for (i = 3; i < 16; i++){if (arr[i] == 2){SumValue = i - 10;prov++;retCardGroupData.nMaxCard = i;}}if (prov == 1){retCardGroupData.cgType = cgDOUBLE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//三条类型if (nCount == 3){//用于验证的变量int prov = 0;int SumValue = 0;int i = 0;for (i = 3; i < 16; i++){if (arr[i] == 3){SumValue = i - 10;prov++;retCardGroupData.nMaxCard = i;}}if (prov == 1){retCardGroupData.cgType = cgTHREE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//三带一单if (nCount == 4){//用于验证的变量int prov1 = 0;int prov2 = 0;int SumValue = 0;for (int i = 3; i < 18; i++){if (arr[i] == 3){SumValue = i - 10;prov1++;retCardGroupData.nMaxCard = i;}if (arr[i] == 1){prov2++;}}if (prov1 == 1 && prov2 == 1){retCardGroupData.cgType = cgTHREE_TAKE_ONE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//三带一对if (nCount == 5){//用于验证的变量int prov1 = 0;int prov2 = 0;int SumValue = 0;for (int i = 3; i < 16; i++){if (arr[i] == 3){SumValue = i - 10;prov1++;retCardGroupData.nMaxCard = i;}if (arr[i] == 2){prov2++;}}if (prov1 == 1 && prov2 == 1){retCardGroupData.cgType = cgTHREE_TAKE_TWO;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//四带两单if (nCount == 6){//用于验证的变量int prov1 = 0;int prov2 = 0;int SumValue = 0;for (int i = 3; i < 18; i++){if (arr[i] == 4){SumValue = (i - 3) / 2;prov1++;retCardGroupData.nMaxCard = i;}if (arr[i] == 1|| arr[i] == 2){prov2+= arr[i];}}if (prov1 == 1 && prov2 == 2){retCardGroupData.cgType = cgFOUR_TAKE_ONE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//四带两对if (nCount == 8){//用于验证的变量int prov1 = 0;int prov2 = 0;int SumValue = 0;for (int i = 3; i < 16; i++){if (arr[i] == 4){SumValue = (i - 3) / 2;prov1++;retCardGroupData.nMaxCard = i;}if (arr[i] == 2|| arr[i] == 4){prov2+= arr[i]/2;}} //注意这里prov2==4因为四牌也是两个对if (prov1 == 1 && prov2 == 4){retCardGroupData.cgType = cgFOUR_TAKE_TWO;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//炸弹类型if (nCount == 4){//用于验证的变量int prov = 0;int SumValue = 0;for (int i = 3; i < 16; i++){if (arr[i] == 4){SumValue += i - 3 + 7;prov++;retCardGroupData.nMaxCard = i;}}if (prov == 1){retCardGroupData.cgType = cgBOMB_CARD;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//王炸类型if (nCount == 2){int SumValue = 0;if (arr[17] > 0 && arr[16] > 0){SumValue = 20;retCardGroupData.nMaxCard = 17;retCardGroupData.cgType = cgKING_CARD;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//单连类型if (nCount >= 5){//用于验证的变量int prov = 0;int SumValue = 0;int i;for (i = 3; i < 15; i++){if (arr[i] == 1){prov++;}else{if (prov != 0){break;}}}SumValue = i - 10;if (prov == nCount){retCardGroupData.nMaxCard = i-1;retCardGroupData.cgType = cgSINGLE_LINE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//对连类型if (nCount >= 6){//用于验证的变量int prov = 0;int SumValue = 0;int i;for (i = 3; i < 15; i++){if (arr[i] == 2){prov++;}else{if (prov != 0){break;}}}SumValue = i - 10;if (prov * 2 == nCount){retCardGroupData.nMaxCard = i - 1;retCardGroupData.cgType = cgDOUBLE_LINE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//三连类型if (nCount >= 6){//用于验证的变量int prov = 0;int SumValue = 0;int i;for (i = 3; i < 15; i++){if (arr[i] == 3){prov++;}else{if (prov != 0){break;}}}SumValue = (i - 3) / 2;if (prov * 3 == nCount){retCardGroupData.nMaxCard = i - 1;retCardGroupData.cgType = cgTHREE_LINE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//三带一连类型if (nCount >= 8){//用于验证的变量int prov1 = 0;int SumValue = 0;int i, j;for (i = 3; i < 15; i++){if (arr[i] >= 3){prov1++;}else{if (prov1 != 0){break;}}}SumValue = (i - 3)/2;if (prov1 * 4 == nCount){retCardGroupData.nMaxCard = i - 1;retCardGroupData.cgType = cgTHREE_TAKE_ONE_LINE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}//三带二连类型if (nCount >= 10){//用于验证的变量int prov1 = 0;int prov2 = 0;int SumValue = 0;int i, j;for (i = 3; i < 15; i++){if (arr[i] == 3){prov1++;}else{if (prov1 != 0){break;}}}for (j = 3; j < 16; j++){if (arr[j] == 2|| arr[j] == 4){prov2+= arr[j]/2;}}SumValue = (i - 3) / 2;if (prov1 == prov2&&prov1 * 5 == nCount){retCardGroupData.nMaxCard = i - 1;retCardGroupData.cgType = cgTHREE_TAKE_TWO_LINE;retCardGroupData.nValue = SumValue;return retCardGroupData;}}retCardGroupData.cgType = cgERROR;return retCardGroupData;}/*检查剩余的牌是否只是一手牌(vector重载)是: 返回手牌类型数据不是:返回错误类型(cgERROR)*/CardGroupData ins_SurCardsType(vector<int>list){int arr[18];memset(arr, 0, sizeof(arr));for (vector<int>::iterator iter = list.begin(); iter != list.end(); iter++){arr[*iter]++;}return ins_SurCardsType(arr);}
怎么样,这么多牌型枚举是不是很头疼?放心吧,接下来的主动出牌算法、被动出牌算法的枚举会更头疼!
所以~从下一章开始我们就要讲出牌的策略了,首先是被动出牌。
敬请关注下一章:斗地主AI算法——第七章の被动出牌(1)
1 0
- 斗地主AI算法——第六章の牌型判断
- 斗地主AI算法——第二章の数据结构
- 斗地主AI算法——第三章の数据处理
- 斗地主AI算法——第七章の被动出牌(1)
- 斗地主AI算法——第八章の被动出牌(2)
- 斗地主AI算法——第九章の被动出牌(3)
- 斗地主AI算法——第十章の被动出牌(4)
- 斗地主AI算法——第十一章の被动出牌(5)
- 斗地主AI算法——第十二章の主动出牌(1)
- 斗地主AI算法——第十三章の主动出牌(2)
- 斗地主AI算法——第十四章の主动出牌(3)
- 斗地主AI算法——第一章の业务逻辑
- 斗地主AI算法——第四章の权值定义
- 斗地主AI算法——第五章の总值计算
- 斗地主AI算法——第十五章の测试模块
- 斗地主AI算法——第十六章の样例分析
- 斗地主AI算法——第十七章の总结整理
- unity开发 斗地主算法—提示AI(提示出牌)
- Angular第一天学习
- unit5~~使用逻辑卷管理器管理灵活存储
- opencv笔记(4):边缘检测
- Activity生命周期
- 表达式求值(栈(操作数栈+操作符栈))
- 斗地主AI算法——第六章の牌型判断
- lightOj 1341Aladdin and the Flying Carpet 算数基本定理
- OSTU 最佳全局阈值处理-最大类间方差法
- docker时间校正
- Spring学习笔记之Spring Security
- 返回引用的意义 作用 未完成
- Sudoku(模拟)
- 剑指offer-18.二叉树的镜像
- davinci_u-boot_env.txt