斗地主算法判断牌型

由于近年来网络棋牌游戏的火爆导致个各个地区的特色棋牌游戏开发进入红火时期,也有越来越多的团队个人开始研究棋牌游戏的开发,所以本文主旨在于各个开发人员之间的交流。

每个游戏都有属于自己的规则,当然斗地主也不例外,常斗地主的朋友可能知道在斗地主里面一共有13种牌型,你所出的牌必须符合13种的一种才能够出得了牌,这个就叫地主的规则。那么我们下面可以通过一个枚举结构来表示每一种的牌型,在这里我们把错误的牌型也当成是一种牌型。

那么在编程中我们该怎么来判断一组牌到底该属于哪一种牌型了??

?这就是接下来我们将解决的问题,本文中可能有些判断牌型的方法不是很好,如果你有更好的方法,欢迎留言指导!~(@^_^@)~!!

首先我们可以根据穷举的方式来罗列一下。在我以前写斗地主的时候我是根据出牌的张数来罗列牌型的,下面我也将使用这种方法,因为没有找到什么更好的方法,嘿嘿!!那就让我们开始吧!

牌的张数 ? 可能的牌型

1张牌 ? ? ? ? 单牌

2张牌 ? ? ? ? 对子(排除对鬼,因为这个在出牌中出现的次数比较少)

3张牌 ? ? ? ?3不带

4张牌 ? ? ? 3带一 ?炸弹

5张牌 ? ? ? 连牌,3带1对

6,7,8,9………

这里我们可以用出牌张数5作为分界线,因为5刚好是连牌的起始数并且出牌张数大于5之后就比较的复杂了。

我们首先定义一个数组来存放即将出牌的牌值。

在判断牌型之前将数组排序,排序规则:如果每张牌出现的次数一样,由小到大,如果不一样就将出现次数比较多的牌放在前面。比如(7,7,3,7)排序之后就变为(7,7,7,3),这样便于我们后面的判断。

出牌张数<5

我们只需判断第一张和最后一张牌的牌值时候相等(因为我们数组已经按照我们事先的规则排序了),如果相等则直接返回牌的张数,这里牌的张数刚好对应我们前面定义的枚举结构值。如果不相等这里要分情况,当出牌的张数等于4时,判断第一张的牌值是否等于倒数第2张,如果相等我们可以直接返回THREE_ONE_CARD牌型,其余的情况可以直接返回ERROR_CARD 。

出牌张数>=5

当出牌张数大于5张时,所组成的牌型就比较的复杂了,可以有连牌,连对,飞机,4带2等一系列牌型。

我们先来分析一下每种牌型组成的情况

连牌:由所有的单牌组成

连队:由所有的对子组成

飞机:由3个+对子,或者3个,或者3个+单张

4带2:4个+2张单牌,4个+2对牌,4个+1对牌

写一个计算数组中所有值是否为连续的方法。我们假设这个函数名叫做CheckContinuous,如果全连续返回true,否则返回false

下面是没种牌型的具体检查方法。

连牌牌型:if(CheckContinuous(出牌数组)==true)出牌数组中所有牌的牌值必须小于2

连队牌型:将出牌数组中的对子,挨个抽出,看是否还有剩余的牌,如果有剩余的牌就说明不能组成连队,则进行下面牌型的判断。如果没有剩余的牌,再根据判断连牌的方法来判断。(筛选条件:张数>=6张&&张数%2==0)

飞机和4带2就比较的复杂了,因为这2种牌型不像上面2种那样组成的牌比较单一,这2种牌型可以由很多种牌来组成。

接下来我们就可以定义一个结构体,来记录每种牌(单个,对子,3个,4个)出现的次数。最后我们只要根据结构体中每种牌出现的数量就很容易判断出到底是什么牌了。

struct ?CRAD_INDEX

{

vector <int > ?single_index;//记录单张的牌

vector<int> doble_index; //记录对子的牌

vector<int >three_index;//记录3张

vector<int> four_index;//记录张

}

飞机牌型:

我们把能组成飞机的所有牌型列举出来:?333444,33344456,3334445566,

通过一个遍历记录方法,上面结构体的值就变成这样了。

333444

single_index ? ? ? ? ? ? ?空

doble_index ? ? ? ? ? ? ??空

three_index ? ? ? ? ? ? ? 3,4

four_index ? ? ? ? ? ? ? ? ?空

33344456

single_index ? ? ? ? ? ? 5,6

doble_index ? ? ? ? ? ???空

three_index ? ? ? ? ? ? ? 3,4

four_index ? ? ? ? ? ? ? ? 空

3334445566

single_index ? ? ? ? ? ? ?空

doble_index ? ? ? ? ? ? ?5,6

three_index ? ? ? ? ? ? ? 3,4

four_index ? ? ? ? ? ? ? ? 空

这3种飞机牌型都有一个共同点,three_index 中的数据必须为连续的并且four_index 必须为空。这个也是最开始筛选的条件之一,如果这个条件都不满足则直接返回。

如果上面个条件满足,接下来计算一下牌的数量就OK了

飞机不带:three_index .sziz()*3==出牌的数量&&single_index+doble_index ?==0

飞机带1张 :three_index .sziz()*3+single_index.size()==出牌的数量&&doble_index.size()==0

飞机带1对:three_index .sziz()*3+doble_index.size()*2==出牌的数量&&single_index.size()==0

同样4带2也可以这样来分析

4带2牌型(牌张数%2==0)

还是像上面一样来列举出具体的牌型来判断

444423 ?444422?44442233

4个带单张

444423

single_index ? ? ? ? ? ? ?2,3

doble_index ? ? ? ? ? ? 空

three_index ? ? ? ? ? ? ? 空

four_index ? ? ? ? ? ? ? ? 4

444422

single_index ? ? ? ? ? ? 空

doble_index ? ? ? ? ? ? 2

three_index ? ? ? ? ? ? ? 空

four_index ? ? ? ? ? ? ? ? 4

4个带2对

44442233

single_index ? ? ? ? ? ? 空

doble_index ? ? ? ? ? ? 2,3

three_index ? ? ? ? ? ? ? 空

four_index ? ? ? ? ? ? ? ? 4

首先找出必须满足的条件:four_index .size()必须等于1,并且出牌张数%2==0,并且three_index.size()==0

如果这个条件不满足则直接进行下面牌型的判断

如果满足就计算牌的张数

4带1

第一种情况: 带2张单牌

((four_index.size()==1&&single_index.size()==2)||(four_index.size()+single_index.size()*4==出牌的张数))

第二种情况 :带2对牌

((four_index.size()==1&&doble_index.size()==1)||(four_index.size()*2+single_index.size()*4==出牌的张数))

4带2对

((four_index.size()==1&&doble_index.size()==2)||(four_index.size()*2+single_index.size()*4==出牌的张数))

原文地址:https://www.cnblogs.com/upupup02/p/10967030.html

时间: 2024-08-29 11:39:00

斗地主算法判断牌型的相关文章

棋牌游戏开发之地主算法判断牌型

棋牌游戏开发疑问交流 QQ:325131039(勿发广告) 棋牌游戏开发技术交流群: 490287966(勿发广告) ps: 本文转载自博主 wojiushi3344 每个游戏都有属于自己的规则,当然地主也不例外,常斗地主的朋友可能知道在斗地主里面一共有13种牌型,你所出的牌必须符合13种的一种才能够出得了牌,这个就叫地主的规则.那么我们下面可以通过一个枚举结构来表示每一种的牌型,在这里我们把错误的牌型也当成是一种牌型. [cpp] view plaincopy enum  CARD_TYPE

斗地主牌型基本算法升级版本

斗地主牌型基本算法升级版本 好久没更新博客了,前段时间和朋友一起开了一个公司 做APP,最后失败了.现在又开始做棋牌游戏了,最近在看网狐的源码,发现里面斗地主的基本算法太强大了,现在想想我原来的算法简直是弱爆了,分享一下 希望能对你有一点点帮助.以下主要涉及到判断牌型,牌型大小比较2块,如果你想了解更多关于棋牌游戏的东西请访问我的 棋牌游戏专栏. 一.判断牌型 定义一个结构来表示每张相同牌的信息. //分析结构 structtagAnalyseResult { BYTE cbFourCount;

斗地主基本牌型判断

/** * Created by xujw on 2017/10/16. * 斗地主 * 单副扑克 * 没有癞子玩法 * 牌对象为{grade:3,face:1} * grade 牌面点数(3-13:3-K, 14:A, 15:2, 16:小王 17:大王) * face 牌面花色(1:黑桃.2:红桃.3:梅花.4:方块) */ var CARD_TYPE_INVALID = -1; // 无效手牌 var CARD_TYPE_SINGLE = 1; // 单张 var CARD_TYPE_DO

棋牌游戏开发之斗地主算法点选牌

这是转载一位博有的....依稀记得..... 斗地主算法之点选牌                            -------                                     有棋牌游戏开发经验的可以来互相交流 QQ:325131039                    棋牌游戏开发技术交流群: 490287966               PS:最近找了几个个朋友主准备把斗地主游戏重写,由于种种原因今天还没有开始,所以先把基本的算法写一写,为以后写项目做准

[算法]一整型数组,除了0之外,其他不重复,判断数组元素是否相邻

数组元素是非负整数,0可以化为任意正整数,要求时间复杂度为O(n) 觉得很奇怪的题目,遍历一次找到最值相减得到极差就行了,如果极差小于数组长度n,则元素相邻,否则不相邻 bool is_adjacent(int* a, int n){ int min = 65535, max = 0; for(int i = 0; i < n; ++i){ if(!a[i] && a[i] < min){ min = a[i]; } else if(!a[i] && a[i]

斗地主特殊牌型定义

游戏内一些牌型的定义,不做过多解释代码很详细,哪有不懂可以留言询问 public enum DDZPaiType { HuoJian("火箭",30,"HuoJian"), ZhaDan("炸弹",20,"ZhaDan"), DanPai("单牌",10,"DanPai"), DuiPai("对牌",10,"DuiPai"), SanZhangPa

【斗地主技巧】斗地主算法逻辑中的天之道&lt;转&gt;

******************************************************************** 作者比较喜欢玩斗地主,所以经常搜集一些网友斗地主的心得,下面这一篇,我感觉写得不错,特转载,与网友分享.原文链接 棋牌游戏推荐:JJ比赛 我比较喜欢在这上面玩,可以赢话费,而且积累的金币其实是可以兑换成人民币的,网上有人回收. *******************************************************************

斗地主AI出牌

斗地主游戏的初期版本目前为止大概已经完成的一半了... 还剩下最麻烦的部分(AI)没写,写这篇博文主要是想理一下基本的思路,然后把这一部分也搞完. 先上一个目前的进度截图纪念一下好了 经过较长时间的冥思苦想,包括网上找资料...(网上关于斗地主AI的资料很少.) 终于想到了一个大概可行的办法~先写出来试试吧.. 斗地主的AI部分主要分为两块: 一个是主动出牌.(自己是第一个出牌的,或者上一把打出的牌没有人要,又轮到自己了) ---这时候就需要从当前的手牌中选取一道合适的牌打出. 怎样选取呢?这正

编程算法 - 判断二叉树是不是平衡树 代码(C)

判断二叉树是不平衡树 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一颗二叉树的根结点, 判断该树是不是平衡二叉树. 二叉平衡树: 任意结点的左右子树的深度相差不超过1. 使用后序遍历的方式, 并且保存左右子树的深度, 进行比较. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <std