/// <summary>
        /// 摊牌检测
        /// 1. 有王没炸弹
        /// 2. 达到炸弹封顶
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        private static bool CheckTanCard(this GameController self)
        {
            Room room     = self.GetParent <Room>();
            var  gameInfo = room.GetComponent <GameInfo>();

            foreach (Player player in room.Players)
            {
                var cards = player.GetComponent <HandCardsComponent>().Cards;
                List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);
                int jokerCount = analyseResults.GetJokerCount();
                if (jokerCount == 4)
                {
                    return(true);
                }

                // 炸弹
                analyseResults = analyseResults.GetBooms();

                // 有王没有炸弹
                if (jokerCount > 0 && analyseResults.Count == 0)
                {
                    return(true);
                }

                // 炸弹封顶
                if (analyseResults.Any(result => result.Count + jokerCount >= gameInfo.BoomTop))
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// 王罚分
        /// </summary>
        /// <param name="self"></param>
        private static void JokerScore(this GameController self)
        {
            var room = self.GetParent <Room>();

            foreach (Player player in room.Players)
            {
                var cards = player.GetComponent <HandCardsComponent>().Cards;
                if (cards.Count == 0)
                {
                    continue;
                }

                List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);

                // 一旦存在炸弹,就不需要罚王了。
                if (analyseResults.Any(f => f.Count >= 4 && !CardsHelper.IsJoker(f.Weight)))
                {
                    continue;
                }

                int jokerCount = analyseResults.GetJokerCount();

                // joker数量为4不需要罚王,算做9炸分.
                if (jokerCount == 4)
                {
                    continue;
                }

                // 罚分
                self.SetScore(player, -(jokerCount * 3));
            }
        }
Exemple #3
0
        /// <summary>
        /// 炸弹排序
        /// 玩家手牌视图的两种排序(普通排序、炸弹排序)
        /// 炸弹提出来最后
        /// </summary>
        /// <param name="cards"></param>
        /// <param name="jokerBefore"></param>
        public static void BoomSort(List <Card> cards, bool jokerBefore = true)
        {
            Sort(cards);

            // 分析牌的数量
            List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);

            // 王的数量
            int jokerCount = analyseResults.Count(f => f.Weight == CardWeight.SJoker || f.Weight == CardWeight.LJoker);

            // 数量>=4的牌就是炸弹
            analyseResults = analyseResults.Where(analyseResult => analyseResult.Count >= 4).ToList();

            // 没有一个炸弹
            if (analyseResults.Count == 0)
            {
                return;
            }

            // 如果joker数量有4个,就归为炸弹.
            if (jokerCount != 4)
            {
                if (!jokerBefore)
                {
                    jokerCount = 0;
                }
            }

            // 先把炸弹按照数量进行,再把炸弹插入到所有joker的前面。
            analyseResults.Sort((a, b) =>
            {
                int x = a.Count * 100 + (int)a.Weight;
                int y = b.Count * 100 + (int)b.Weight;
                if (x > y)
                {
                    return(1);
                }

                if (x < y)
                {
                    return(-1);
                }

                return(0);
            });

            // 移除炸弹牌,如果需要插入到王前面就放到前面,不需要就插入到尾巴上.
            foreach (AnalyseResult result in analyseResults)
            {
                foreach (Card card in result.Cards)
                {
                    cards.Remove(card);
                    cards.Insert(cards.Count - jokerCount, card);
                }
            }
        }
        /// <summary>
        /// 配王算分
        /// </summary>
        /// <param name="self"></param>
        private static void FetchJokerBoomScore(this GameController self)
        {
            var room     = self.GetParent <Room>();
            var gameInfo = self.Parent.GetComponent <GameInfo>();

            foreach (Player player in room.Players)
            {
                List <Card> cards = player.GetComponent <HandCardsComponent>().Cards;
                if (cards.Count == 0)
                {
                    continue;
                }

                List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);
                int jokerCount = analyseResults.GetJokerCount();
                if (jokerCount == 4)
                {
                    self.BoomScore(player, gameInfo.BoomTop);
                    jokerCount = 0;
                }

                analyseResults = analyseResults.GetBooms();

                // 按照数量降序
                analyseResults.Sort();

                // 配王
                foreach (AnalyseResult analyseResult in analyseResults)
                {
                    // 最多8张牌
                    int boomCount = analyseResult.Count;

                    if (jokerCount > 0)
                    {
                        // 需要多少张王
                        int a = gameInfo.BoomTop - boomCount;

                        // 取小(jokerCount,a)
                        a = a > jokerCount? jokerCount : a;

                        // 减去用了的
                        jokerCount -= a;

                        // 配上的
                        boomCount += a;
                    }

                    self.BoomScore(player, boomCount);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// 炸弹:四个(含四个)以上相同点的牌叫炸弹,可以炸任何类型的牌,炸弹的大小 按数量及2>A>K>Q>J>10>9……..3排序,相同数目的炸按先出顺序比大小(如:四个3先出,则后出的四个3不能压)。
        /// </summary>
        /// <param name="cards"></param>
        /// <returns></returns>
        public static bool IsBoom(List <Card> cards)
        {
            // 炸弹最少4张牌, 最多12张
            if (cards.Count < 4 || cards.Count > 12)
            {
                return(false);
            }

            List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);

            // 结果不能大于3种,因为不算花色,加上大小王最多3种牌。
            if (analyseResults.Count > 3)
            {
                return(false);
            }

            // 只有一种牌,并且大于等于4张
            if (analyseResults.Count == 1 && analyseResults[0].Count >= 4)
            {
                return(true);
            }

            // 把王排除掉,后有且只能有一种牌。
            int jokerCount = analyseResults.Count(f => f.Weight == CardWeight.LJoker || f.Weight == CardWeight.SJoker);

            if (analyseResults.Count - jokerCount != 1)
            {
                return(false);
            }

            // 并且剩下的那种牌的数量必须>=4
            foreach (AnalyseResult analyseResult in analyseResults)
            {
                // 跳过王
                if (analyseResult.Weight == CardWeight.LJoker || analyseResult.Weight == CardWeight.SJoker)
                {
                    continue;
                }

                if (analyseResult.Count < 4)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #6
0
        /// <summary>
        /// 特殊牌型,4张王,最大的8炸。
        /// </summary>
        /// <param name="cards"></param>
        /// <returns></returns>
        public static bool IsJokerBoom(List <Card> cards)
        {
            if (cards.Count != 4)
            {
                return(false);
            }

            List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);

            if (analyseResults.Count != 2)
            {
                return(false);
            }

            // 4张王
            return(analyseResults[0].Count == 2 && analyseResults[1].Count == 2 && IsJoker(analyseResults[0].Weight) &&
                   IsJoker(analyseResults[1].Weight));
        }
Exemple #7
0
        /// <summary>
        /// 数量权重排序
        /// 一些牌型验证需要使用
        /// 比如出三带二、连三带二时、炸弹时。多的牌在前面
        /// </summary>
        /// <param name="cards"></param>
        public static void WeightSort(List <Card> cards)
        {
            Sort(cards);

            // 分析每张牌的数量
            List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);

            // 按照数量以及权重进行牌型,数量>权重
            analyseResults.Sort();

            // 从排序结果中
            cards.Clear();
            foreach (AnalyseResult result in analyseResults)
            {
                if (result.Count > 0)
                {
                    cards.AddRange(result.Cards);
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// 连三带二:牌点连续的两个(含两个)以上的三张+随意4张(6张、8张、、、,2不出现连三中)
        /// </summary>
        /// <returns></returns>
        public static bool IsTripleStraight(List <Card> cards)
        {
            // 牌数不对
            if (cards.Count < 10 || cards.Count % 5 != 0)
            {
                return(false);
            }

            List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);

            // 3张的牌有几个
            analyseResults = analyseResults.Where(f => f.Count >= 3).ToList();

            // 匹配成功目标个数
            int targetNum = cards.Count / 5;

            int matchNum = 0;

            // 3张的牌的权重依次递增: 3334443456需要给通过,但视图现在显示为:3333444456
            // 3335556668

            // 反向判定,按出牌最大的权重算. 3334445556 : 444555
            for (int i = analyseResults.Count - 1; i > 0; i++)
            {
                // 排除2
                if (analyseResults[i].Weight - analyseResults[i - 1].Weight == 1 &&
                    analyseResults[i].Weight != CardWeight._2 &&
                    analyseResults[i - 1].Weight != CardWeight._2)
                {
                    matchNum += 2;
                    if (matchNum == targetNum)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #9
0
        /// <summary>
        /// 获取牌组权重
        /// 已经按照数量权重排序
        /// </summary>
        /// <param name="cards"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static int GetWeight(this IReadOnlyList <Card> cards, CardType type)
        {
            int w = 0;

            switch (type)
            {
            case CardType.None:
                break;

            case CardType.ThreeAndTwo:
            {
                w += (int)cards[0].Weight * 3;
                break;
            }

            case CardType.TripleStraight:
            {
                // 需要进行分析,因为特殊牌型:3333344444 3333444456 再排序上是挨着一起的。
                List <AnalyseResult> analyseResults = AnalyseResult.Analyse(cards);

                // 需要计算的次数
                int targetNum = cards.Count / 5;
                int matchNum  = 0;
                analyseResults = analyseResults.Where(f => f.Count >= 3).ToList();

                // 反向求权重,按出牌最大的权重算. 3334445556 : 444555
                for (int i = analyseResults.Count - 1; i > 0; i++)
                {
                    // 排除2
                    if (analyseResults[i].Weight - analyseResults[i - 1].Weight == 1 &&
                        analyseResults[i].Weight != CardWeight._2 &&
                        analyseResults[i - 1].Weight != CardWeight._2)
                    {
                        w        += (int)analyseResults[i].Weight * 3;
                        w        += (int)analyseResults[i - 1].Weight * 3;
                        matchNum += 2;
                        if (matchNum == targetNum)
                        {
                            break;
                        }
                    }
                }

                break;
            }

            case CardType.Boom:
                // 数量占大头 + 除王的权重值
                w = int.MaxValue / 2 + cards.Count * 100 + cards.Where(card => !IsJoker(card)).Sum(card => (int)card.Weight);
                break;

            case CardType.JokerBoom:
                w = int.MaxValue;
                break;

            // 直接求和的
            case CardType.Single:
            case CardType.Double:
            case CardType.OnlyThree:
            case CardType.DoubleStraight:
            case CardType.Straight:
            default:
                w = cards.Sum(c => (int)c.Weight);
                break;
            }

            return(w);
        }