http://blog.csdn.net/aojiancc2/article/details/17166305五

斗地主的出牌规则不过有两点

1:自己出的牌是否符合规则

2:牌能否大过上家

所以我们需要建立一个牌的类型枚举,如果在该枚举中才允许出牌,每个类型需要对应一个tag用于标记该类型对应最大的牌

这样我们和上家去比较就非常方便了,比如牌的类型是顺子那么tag应该标记顺子中最大的,

如果是飞机应该标记三同中最大的

我们来分析一下斗地主需要的对象:玩家,牌

这里分析一下牌的对象

属性:

1:牌的类型

2:tag标记该类型牌最大的参数

3:出的牌

4:用户手中的牌

5:底牌

方法:

1:IsThan是否大过上家

2:Put出牌

3:Deal发牌

4:GetPokerType给牌归下类以便好判断牌的类型与找到标记

先建立枚举(这里可以允许连续炸弹类型):

public enum PokerGroupType : int{单子 = 1,//1张牌对子 = 2,//2张牌双王 = 3,三不带 = 4,//3张牌炸弹 = 5,//4张牌三带一 = 6,五张顺子 = 7,//5张牌三带一对 = 8,六张顺子 = 9,//6张牌三连对 = 10,四带二 = 11,二飞机不带 = 12,七张顺子 = 13,四连对 = 14,//8张牌八张顺子 = 15,二飞机带2单 = 16,四带2对 = 17,九张顺子 = 18,//9张牌三飞机不带 = 19,五连对 = 20,//10张牌十张顺子 = 21,飞机带2对 = 22,十一张顺子 = 23,十二张顺子 = 24,//12张牌四飞机不带 = 25,三飞机带3张 = 26,六连对 = 27,两个4带2 = 28,七连对 = 29,//14张牌五飞机不带 = 30,//15张牌三飞机带三对 = 31,八连对 = 32,//16张牌四连飞机带4单 = 33,两个4带两对 = 34,九连对 = 35,//18张牌六连飞机不带 = 36,三个四个二 = 37,十连对 = 38,//20张牌四飞机带4对 = 39,五飞机带5单 = 40}

为了更好的判断牌的类型我们用一个方法给生成的牌归下类

public int GetPokerType(int _pokertype){if (_pokertype <= 3 && _pokertype >= 0) //0-3都是3return 3;if (_pokertype <= 7 && _pokertype >= 4) //4-7都是4return 4;if (_pokertype <= 11 && _pokertype >= 8)return 5;if (_pokertype <= 15 && _pokertype >= 12)return 6;if (_pokertype <= 19 && _pokertype >= 16)return 7;if (_pokertype <= 23 && _pokertype >= 20)return 8;if (_pokertype <= 27 && _pokertype >= 24)return 9;if (_pokertype <= 31 && _pokertype >= 28)return 10;if (_pokertype <= 35 && _pokertype >= 32)return 11;if (_pokertype <= 39 && _pokertype >= 36)return 12;if (_pokertype <= 43 && _pokertype >= 40)return 13;if (_pokertype <= 47 && _pokertype >= 44)return 14;if (_pokertype <= 51 && _pokertype >= 48) //都是2return 15;if (_pokertype == 52) //小王return 16;if (_pokertype == 53)//大王return 17;return -1;}

出牌规则类:验证自己是否能出牌与标记相应类型tag

public class PokerRule
{
public bool IsRule(Poker_ddz _pokers) //出牌是否符合规则与类型
{
_pokers.putpokers.Sort();
int num = _pokers.putpokers.Count;
bool res = false;
switch (num)
{
case 1:
_pokers.pgt = PokerGroupType.单子;
_pokers.tagnum = _pokers.putpokers[0];
res = true;
break;
case 2:
if (Same(_pokers))
{
_pokers.pgt = PokerGroupType.对子;
res = true;
}
else if (_pokers.putpokers[0] == 16 && _pokers.putpokers[1] == 17)
{
_pokers.pgt = PokerGroupType.双王;
res = true;
}
break;
case 3:
if (Same(_pokers))
{
_pokers.pgt = PokerGroupType.三不带;
res = true;
}
break;
case 4:
if (Same(_pokers))
{
_pokers.pgt = PokerGroupType.炸弹;//先判断炸弹别把炸弹理解成3个带一个了
res = true;
}
else if (IsPlaneWithOne(_pokers))
{
_pokers.pgt = PokerGroupType.三带一;
res = true;
}
break;
case 5:
if (IsStraight(_pokers))
{
_pokers.pgt = PokerGroupType.五张顺子;
res = true;
}
else if (IsPlaneWithTwo(_pokers))
{
_pokers.pgt = PokerGroupType.三带一对;
res = true;
}
break;
case 6:
if (IsStraight(_pokers))
{
_pokers.pgt = PokerGroupType.六张顺子;
res = true;
}
else if (IsFourWithTwoSimple(_pokers))
{
_pokers.pgt = PokerGroupType.四带二;
res = true;
}
else if (IsStraightPair(_pokers))
{
_pokers.pgt = PokerGroupType.三连对;
res = true;
}
else if (IsPlaneNoWith(_pokers))
{
_pokers.pgt = PokerGroupType.二飞机不带;
res = true;
}
break;
case 7:
if (IsStraight(_pokers))
{
_pokers.pgt = PokerGroupType.七张顺子;
res = true;
}
break;
case 8:
if (IsStraight(_pokers))
{
_pokers.pgt = PokerGroupType.八张顺子;
res = true;
}
else if (IsStraightPair(_pokers))
{
_pokers.pgt = PokerGroupType.四连对;
res = true;
}
else if (IsPlaneWithOne(_pokers))
{
_pokers.pgt = PokerGroupType.二飞机带2单;
res = true;
}
else if (IsFourWithTwoPair(_pokers))
{
_pokers.pgt = PokerGroupType.四带2对;
res = true;
}
break;
case 9:
if (IsStraight(_pokers))
{
_pokers.pgt = PokerGroupType.九张顺子;
res = true;
}
else if (IsPlaneNoWith(_pokers))
{
_pokers.pgt = PokerGroupType.三飞机不带;
res = true;
}
break;
case 10:
if (IsStraight(_pokers))
{
_pokers.pgt = PokerGroupType.十张顺子;
res = true;
}
else if (IsStraightPair(_pokers))
{
_pokers.pgt = PokerGroupType.五连对;
res = true;
}
else if (IsPlaneWithTwo(_pokers))
{
_pokers.pgt = PokerGroupType.飞机带2对;
res = true;
}
break;
case 11:
if (IsStraight(_pokers))
{
_pokers.pgt = PokerGroupType.十一张顺子;
res = true;
}
break;
case 12:
if (IsStraight(_pokers))
{
_pokers.pgt = PokerGroupType.十二张顺子;
res = true;
}
else if (IsStraightPair(_pokers))
{
_pokers.pgt = PokerGroupType.六连对;
res = true;
}
else if (IsPlaneWithOne(_pokers))
{
_pokers.pgt = PokerGroupType.三飞机带3张;
res = true;
}
else if (IsPlaneNoWith(_pokers))
{
_pokers.pgt = PokerGroupType.四飞机不带;
res = true;
}
else if (IsFourWithTwoSimple(_pokers))
{
_pokers.pgt = PokerGroupType.两个4带2;
res = true;
}
break;
case 14:
if (IsStraightPair(_pokers))
{
_pokers.pgt = PokerGroupType.七连对;
res = true;
}
break;
case 15:
if (IsPlaneNoWith(_pokers))
{
_pokers.pgt = PokerGroupType.五飞机不带;
res = true;
}
else if (IsPlaneWithTwo(_pokers))
{
_pokers.pgt = PokerGroupType.三飞机带三对;
res = true;
}
break;
case 16:
if (IsPlaneWithOne(_pokers))
{
_pokers.pgt = PokerGroupType.四连飞机带4单;
res = true;
}
else if (IsStraightPair(_pokers))
{
_pokers.pgt = PokerGroupType.八连对;
res = true;
}
else if (IsFourWithTwoPair(_pokers))
{
_pokers.pgt = PokerGroupType.八连对;
res = true;
}
break;
case 18:
if (IsStraightPair(_pokers))
{
_pokers.pgt = PokerGroupType.九连对;
res = true;
}
else if (IsPlaneNoWith(_pokers))
{
_pokers.pgt = PokerGroupType.六连飞机不带;
res = true;
}
else if (IsFourWithTwoSimple(_pokers))
{
_pokers.pgt = PokerGroupType.三个四个二;
res = true;
}
break;
case 20:
if (IsStraightPair(_pokers))
{
_pokers.pgt = PokerGroupType.十连对;
res = true;
}
else if (IsPlaneWithTwo(_pokers))
{
_pokers.pgt = PokerGroupType.四飞机带4对;
res = true;
}
else if (IsPlaneWithOne(_pokers))
{
_pokers.pgt = PokerGroupType.五飞机带5单;
res = true;
}
break;
default: return false;
}
return res;
}
public bool Same(Poker_ddz _pokers)//是否手中的所有牌相同
{
for (int i = 0; i < _pokers.putpokers.Count - 1; i++)
{
if (_pokers.putpokers[0] != _pokers.putpokers[i + 1])
return false;
}
_pokers.tagnum = _pokers.putpokers[_pokers.putpokers.Count - 1];
return true;
}
public bool IsHaveFourStaright(Poker_ddz _pokers, List<int> foursame, int onesame) //验证是否有4个的,与4个的是否连续
{
if (foursame.Count == 1 && foursame.Count * 2 == onesame)//验证是否有4个的,且一个4个的能带两个单张,普通4带2
{
_pokers.tagnum = foursame[foursame.Count - 1];
return true;
}
else if (foursame.Count > 1 && foursame.Count * 2 == onesame && IsStraight(new Poker_ddz { putpokers = foursame }))//滚筒,4个的是否连续
{
_pokers.tagnum = foursame[foursame.Count - 1];
return true;
}
else
return false;
}
public bool IsFourWithTwoSimple(Poker_ddz _pokers) //是否是4带2单,与滚筒比如333344445678两个4个的带4张
{
List<int> foursame = new List<int>();//4张相同的
int onesame = 0;//所带的单个数
for (int i = 0; i < _pokers.putpokers.Count; i++)
{
int tag = _pokers.putpokers[i];
int count = _pokers.putpokers.Where(a => a == tag).Count();
if (count == 4)
{
foursame.Add(tag);
i = i + 3;
}
else
onesame++;
}
return IsHaveFourStaright(_pokers, foursame, onesame);
}
public bool IsFourWithTwoPair(Poker_ddz _pokers) //是否是4带2对,与滚筒比如333344445566两个4个的带4对
{
List<int> foursame = new List<int>();//4张相同的
int onesame = 0;//所带的对子个数
for (int i = 0; i < _pokers.putpokers.Count; i++)
{
int tag = _pokers.putpokers[i];
int count = _pokers.putpokers.Where(a => a == tag).Count();
if (count == 4)
{
foursame.Add(tag);
i = i + 3;
}
else if (count == 2)
{
i++;
onesame++;
}
else //要带两个除了4个的就必须是对子,如果不是4个的也不是对子那么必然不是4带两对
return false;
}
return IsHaveFourStaright(_pokers, foursame, onesame);
}
public bool IsStraight(Poker_ddz _pokers)//是否为顺子
{
int num = _pokers.putpokers.Where(a => a == 16 || a == 17 || a == 15).Count();//不能包涵王与2
if (num > 0)
return false;
for (int i = 0; i < _pokers.putpokers.Count - 1; i++)
{
if (_pokers.putpokers[i] + 1 != _pokers.putpokers[i + 1])
return false;
}
_pokers.tagnum = _pokers.putpokers[_pokers.putpokers.Count - 1];
return true;
}
public bool IsStraightPair(Poker_ddz _pokers)//是否为联连对
{
int num = _pokers.putpokers.Where(a => a == 16 || a == 17 || a == 15).Count();//不能包涵王与2
if (num > 0)
return false;
for (int i = 0; i < _pokers.putpokers.Count - 2; i++)
{
if (_pokers.putpokers[i] != _pokers.putpokers[i + 1])//相连两个相等
return false;
if (_pokers.putpokers[i] + 1 != _pokers.putpokers[i + 2])//对子之间必须要相隔1
return false;
i = i + 1;//两两比较就行了
}
_pokers.tagnum = _pokers.putpokers[_pokers.putpokers.Count - 1];
return true;
}
public bool IsHavePlaneStaright(List<int> _threesame, List<int> withsame) //验证不否有3个的,与3个的是否连续即是否是飞机
{
if (_threesame.Count < 1)//没有三张相同的
return false;
if (_threesame.Count != 1)//等于1是普通三带一不需要验证是否连续
{
if (!IsStraight(new Poker_ddz { putpokers = _threesame })) //检查相同的是否为连续
return false;
}
if (_threesame.Count != withsame.Count)//验证是否带牌得合理,一个三张牌只能带一张牌或一对牌,所以应该是1比1
return false;
return true;
}
public void ToPlaneTidy(Poker_ddz _pokers, List<int> threesame, List<int> twosame, int _type) //重新理下牌,因为出的飞机可能不是我们想要看到的那样比如3332244455整理成3334442255
{
List<int> pokers = new List<int>();
for (int i = 0; i < threesame.Count; i++)
{
pokers.Add(threesame[0]);
pokers.Add(threesame[0]);
pokers.Add(threesame[0]);
}
for (int j = 0; j < twosame.Count; j++)
{
if (_type == 2)//带1对,就要多添加一次因为他是对子嘛
pokers.Add(twosame[j]);
pokers.Add(twosame[j]);
}
_pokers.putpokers = pokers;
}
public bool IsPlaneNoWith(Poker_ddz _pokers)//是否是飞机不带
{
List<int> recrod = new List<int>();//记录是那几个牌有三张,关键是看是否是连续,不然不能称之为飞机
for (int i = 0; i < _pokers.putpokers.Count; i++)
{
int tag = _pokers.putpokers[i];
int count = _pokers.putpokers.Where(a => a == tag).Count();
if (count == 3) //前三个相等直接比较跳过这三个
{
recrod.Add(tag);
i = i + 2;//本身还要加个一
}
else //三不带必须要每个都是三个
return false;
}
if (recrod.Count < 1)//没有三张相同的
return false;
if (!IsStraight(new Poker_ddz { pokers = recrod })) //检查相同的是否为连续
return false;
_pokers.tagnum = _pokers.putpokers[_pokers.putpokers.Count - 1];
return true;
}
public bool IsPlaneWithOne(Poker_ddz _pokers)//是否是飞机带1
{
List<int> threesame = new List<int>();//记录是那几个牌有三张
List<int> twosame = new List<int>();//记录是单个的牌
for (int i = 0; i < _pokers.putpokers.Count; i++)
{
int tag = _pokers.putpokers[i];
int count = _pokers.putpokers.Where(a => a == tag).Count();
if (count == 3) //前三个相等直接比较跳过这三个
{
threesame.Add(tag);
i = i + 2;
}
else
twosame.Add(tag);
}
if (!IsHavePlaneStaright(threesame, twosame)) //检查相同的是否为连续
return false;
_pokers.tagnum = threesame[threesame.Count - 1];
ToPlaneTidy(_pokers, threesame, twosame, 1);
return true;
}
public bool IsPlaneWithTwo(Poker_ddz _pokers)//是否是飞机带对
{
List<int> threesame = new List<int>();//记录是那几个牌有三张
List<int> twosame = new List<int>();//记录是对子的牌
for (int i = 0; i < _pokers.putpokers.Count; i++)
{
int tag = _pokers.putpokers[i];
int count = _pokers.putpokers.Where(a => a == tag).Count();
if (count == 3) //前三个相等直接比较跳过这三个
{
threesame.Add(tag);
i = i + 2;
}
else if (count == 2)
{
twosame.Add(tag);
i = i + 1;
}
else //三带一对不可能有单张的存在
return false;
}
if (!IsHavePlaneStaright(threesame, twosame)) //检查相同的是否为连续
return false;
_pokers.tagnum = threesame[threesame.Count - 1];//记录最大的一张牌
ToPlaneTidy(_pokers, threesame, twosame, 2);
return true;
}
}

siverlight网络分房间斗地主4出牌规则算法相关推荐

  1. siverlight网络分房间斗地主5网络部分

    http://blog.csdn.net/aojiancc2/article/details/14170221一 这里分析一下玩家的对象 属性: 1:是否准备isready 2:是否是地主island ...

  2. 斗地主自动出牌函数c语言,斗地主AI出牌(示例代码)

    斗地主游戏的初期版本目前为止大概已经完成的一半了... 还剩下最麻烦的部分(AI)没写,写这篇博文主要是想理一下基本的思路,然后把这一部分也搞完. 先上一个目前的进度截图纪念一下好了 经过较长时间的冥 ...

  3. java斗地主怎么出牌_斗地主滑动选牌出牌(Cocos Creator)

    本文主要讲解以下几个方面: card model 滑动处理 阴影 选择 出牌 Card Model 首先,牌有两个属性:数字.花型: ps:本文现在是,用数字和花型来组成一张牌,有空可以再用另一种形式 ...

  4. 跑得快—扑克牌游戏出牌规则(JavaScript)

    第一次写这种棋牌出牌的规则.第一想到的是正则,花了两天时间写出来,反复调试,大致应该没有BUG.代码有点乱,但是具体注释都写了. 规则JS /*** Created by jialin on 2016 ...

  5. DFS+DP搜索斗地主玩家手牌最少出牌次数

    最近在做一个炸弹斗地主的项目,需要搭建一个离线牌库,筛牌就成为了重点.其实别的部门有这块的功能代码,但是时间充裕,自己做做,效率不行的话,再想办法拿人家的代码吧... 与普通斗地主的出牌规则一致: 牌 ...

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

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

  7. 【华为OD机试真题 python】连续出牌数量【2022 Q4 | 200分】

    前言 <华为OD笔试真题 python> 专栏含华为OD机试真题.华为面试题.牛客网华为专栏真题. 如果您正在准备华为的面试,或者华为od的机会,有任何想了解的可以私信我进行交流.我会尽可 ...

  8. 华为机试:连续出牌数量

    [编程题目 |200分]连续出牌数量[2022 Q1,Q2考试题] 题目描述 手里给一副手牌,数字从0-9,有r(红色),,g(绿色),b(蓝色),y(黄色)四种颜色,出牌规则为每次打出的牌必须跟上一 ...

  9. 带赖子的麻将胡牌算法Java_有人讨论下麻将胡牌,出牌算法吗,求思路

    前段时间学会了打麻将,觉得老祖宗的智慧真的博大精深,很好玩,食胡的时候真兴奋啊,于是空余时间就想自己写个麻将游戏出来,模仿欢乐麻将那种,数学差,想了两个礼拜才想出一个胡牌算法,前段时间学会了打麻将. ...

最新文章

  1. C++中一些你不知道的冷知识
  2. SQL Server 判断数据库是否存在,表是否存在
  3. AVL树C++实现(插入,删除,查找,清空,遍历操作)
  4. 「Python」pycharm多项目虚拟环境切换
  5. python tempfile自动删除_Python tempfile模块生成临时文件和临时目录
  6. Dell 电话技术支持工程师答用户问(暴笑)
  7. 不做别人思想的“跑马场”(人民论坛)
  8. wait方法为什么要放在循环里
  9. gdb 的使用 problem solution
  10. linux mysql远程连接
  11. iOS-蓝牙4.0开发(踩过的坑)
  12. android修改状态栏图标大小,安卓手机状态栏图标位置修改教程
  13. 如何快速win10下安装win7双系统
  14. java启动另一个程序_Java操作另一个Java程序使其重启的简单实现
  15. 黑php的称呼,这三个称呼你都说对了吗?
  16. 帝国CMS二次开发在模板里调用本地正规api代码自动生成二维码
  17. 大数据处理应遵循的四大原则
  18. 在PB中计算指定日期相对数量单位前(后)的日期
  19. C++计算圆柱体的表面积
  20. 公司注销后债务承担的法律规定

热门文章

  1. vue 项目 husky pre-commit 勾子不触发
  2. 《伸手系列》第二集-oracle数据库“灾难性”数据恢复-(一)
  3. Zilliz 创始人兼 CEO 星爵当选 2021 中国开源优秀人物
  4. Linux中断子系统(四)之中断申请注册
  5. 《大象——thinking in UML》
  6. 三十而立技术er的进击之路
  7. JS children和childNodes的区别
  8. nfs协议制作服务器,搭建NFS服务器(Setup NFS Server)
  9. 互联网通信安全TCP/IP协议
  10. 静态旅游网站(PC端)