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


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都是3
                return 3;
            if (_pokertype <= 7 && _pokertype >= 4) //4-7都是4
                return 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) //都是2
                return 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;
        }
    }




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值