u3d联机斗地主(1):出牌规则

1出牌类型

    enum CardType
    {
        None = 0,
        One = 1,
        Two = 2,
        Three = 3,
        ThreeWithOne = 4,
        ThreeWithTwo = 5,
        Four = 6,
        FourWith2One = 7,
        FourWith2Two = 8,
        Rocket = 9,
    }

每次出牌都是这9种类型:单张,对子,3连,3带1单,3带1对,4连,4带2个单,4带2个对,大小王

    class CardRule
    {
        public CardType m_type;
        public int m_val; //选取的最小的牌值
        public int m_num = 1; //顺子的数量
}

然后根据出牌判断牌型,例如a玩家出牌:12345,牌型m_type=One,m_val=1,m_num=5。b玩家出牌:23456,牌型m_type=One,m_val=2,m_num=5。满足m_type一样,m_val更大,m_num一样,b玩家的牌就能吃掉a玩家。

例如a玩家出牌:3333444455667788,牌型m_type=FourWith2Two,m_val=3,m_num=2。

2判断一次出牌中每张的数量

static void mapCardCreate(List<int> list, ref Dictionary<int, int> dicCard)
        {
            for (int i = 0; i < list.Count; i++)
            {
                if (dicCard.ContainsKey(list[i]) == false)
                {
                    dicCard.Add(list[i], 1);
                }
                else
                {
                    dicCard[list[i]]++;
                }
            }
        }

用一个字典保存住,键是牌的值,值是这张牌的数量。例如:444422,字典为dic[4]=4,dic [2]=2.

3只有连牌的判断

/// <summary>
        /// 只有顺子处理,例如:34567,334455,333444,44445555
        /// </summary>
        /// <param name="list">出的牌,例如34567</param>
        /// <param name="dicItem">每张牌数量的字典</param>
        /// <param name="dealType">当前处理连牌类型:单连,双连,三连,4连</param>
        /// <param name="val">牌型的最小值</param>
        /// <param name="num">连牌数量</param>
        /// <param name="cardType">牌型</param>
        /// <returns></returns>
        static bool shunOnlyDeal(List<int> list, Dictionary<int, int> dicItem, CardType dealType, ref int val,ref int num, ref CardType cardType)
        {
            int mod = 1;
            int firstVal = 1;
            switch (dealType)
            {
                case CardType.Two:
                    firstVal = 2;
                    mod = 2;
                    break;
                case CardType.Three:
                    firstVal = 3;
                    mod = 3;
                    break;
                case CardType.Four:
                    firstVal = 4;
                    mod = 4;
                    break;
            }
            if (list.Count % mod != 0)
            {
                return false;
            }

            int iNum = 0;
            int minVal = GMaxVal;
            List<int> listKey = new List<int>();
            foreach (var item in dicItem)
            {
                if (item.Value != firstVal )
                {
                    return false;
                }
                if (item.Value == firstVal)
                {
                    iNum++;
                    listKey.Add(item.Key);
                }
                if ((item.Key < minVal) && item.Value == firstVal)
                {
                    minVal = item.Key;
                }  
            }

            if (listKey.Count >= 2)
            {
                listKey.Sort((x, y) => x.CompareTo(y));
                if (isInOrder(listKey) == false)
                {
                    return false;
                }
            }
            val = minVal;
            num = iNum;
            cardType = dealType;
            return true;
        }

例如:当出牌为334455时,双连牌时

1.出牌数量要为2的倍数

2.遍历记录每张牌数量的字典,找到最小牌值minVal =3,记录顺子数量iNum=3

3.得到每张单牌的list(3,4,5),如果它们是按顺序的,则是合法的牌型。

4连牌带牌的判断

/// <summary>
        /// 连牌带牌处理,例如:3334,33344456,333345,33334455
        /// </summary>
        /// <param name="list">出的牌,从大到小排好顺序的</param>
        /// <param name="dicItem">记录每张牌个数的字典</param>
        /// <param name="dealType">处理的类型:3带1单,3带一对,4带2单,4带2对</param>
        /// <param name="val">牌的最小值</param>
        /// <param name="num">牌型数量</param>
        /// <param name="cardType">牌型</param>
        /// <returns></returns>
        static bool shunWithDeal(List<int> list, Dictionary<int, int> dicItem, CardType dealType,ref int val, ref int num,ref CardType cardType)
        {
            int mod = 1;
            int firstVal = 1;//顺子的牌要连几张,3带1,连3张
            int withVal = 1;//顺子带的牌要带几张,3带1,带1张
            int multiple = 1;//顺子与带牌的倍数关系,3带1,倍数为1张
            switch (dealType)
            {
                case CardType.ThreeWithOne:
                    firstVal = 3;
                    withVal = 1;
                    mod = 4;
                    multiple = 1;
                    break;
                case CardType.ThreeWithTwo:
                    firstVal = 3;
                    withVal = 2;
                    mod = 5;
                    multiple = 1;
                    break;
                case CardType.FourWith2One:
                    firstVal = 4;
                    withVal = 1;
                    mod = 6;
                    multiple = 2;
                    break;
                case CardType.FourWith2Two:
                    firstVal = 4;
                    withVal = 2;
                    mod = 8;
                    multiple = 2;
                    break; 
            }
            if (list.Count%mod != 0)
            {
                return false;
            }

            int iNum = 0;//顺子的数量 例如:33334455,顺子数量为1
            int iWithNum = 0;//带牌的数量 例如:33334455,带牌数量为2
            int minVal = GMaxVal;
            List<int> listKey = new List<int>();
            foreach (var item in dicItem)
            {
                if (item.Value != firstVal && item.Value != withVal)
                {
                    return false;
                }
                if (item.Value == withVal)
                {
                    iWithNum++;//累积带牌数量
                }
                if (item.Value == firstVal)
                {
                    iNum++;//累积顺子数量
                    listKey.Add(item.Key);
                }
                if ((item.Key < minVal) && item.Value == firstVal)
                {
                    minVal = item.Key;
                }
            }
            if (iWithNum != iNum * multiple)
            {
                return false;
            }
            if (listKey.Count >= 2)
            {
                listKey.Sort((x, y) => x.CompareTo(y));
                if (isInOrder(listKey) == false)
                {
                    return false;
                }
            }
            val = minVal;
            num = iNum;
            cardType = dealType;
            return true;
        }

这里连牌带牌有4种:3带1单,3带1对,4带2单,4带2对。

例如出牌:3333444455667788,判断出牌型为4带2对,牌值为3,顺子数量为2,带牌数量为4,满足顺子与带牌的倍数:带牌数4=顺子数2*倍数2。

5运行效果

源码下载

http://download.csdn.net/detail/luoyikun/9733173

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

四夕立羽

你的鼓励将是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值