예제 #1
0
        /// <summary>
        /// 和牌判定(包括无役)(请在调用一次_IsHu后立即调用计算番役的程序以便计算本次判定的番役)
        /// </summary>
        /// <param name="Hand_Cards">手牌</param>
        /// <param name="Furu_Cards">副露牌</param>
        /// <returns>是否可和</returns>
        private bool isHu(List <MahjongCard> Hand_Cards, List <MahjongCardFuru> Furu_Cards, out List <HuCard> huCard)
        {
            List <MahjongCard>     hand_cards = new List <MahjongCard>(Hand_Cards);
            List <MahjongCardFuru> furu_cards = new List <MahjongCardFuru>(Furu_Cards);

            // 清空和牌牌组以便计算番役
            huCard = new List <HuCard>();

            // 判断数量
            if (hand_cards.Count + (furu_cards.Count * 3) < 14)
            {
                return(false);
            }

            // 计算两个特殊役种:七对子,十三幺
            if (Furu_Cards.Count == 0)
            {
                // 七对子
                IEnumerable <MahjongCard> cards = from card in Hand_Cards group card by card.name into z where z.Count() == 2 select z.First();

                if (cards.Count() == 7)
                {
                    // 将要和的牌加入和牌牌组以便计算番役
                    foreach (MahjongCard card in cards)
                    {
                        HuCard hucard = new HuCard()
                        {
                            furu = false,
                            type = HuCardType.Finch,
                        };
                        hucard.cards = new List <MahjongCard>()
                        {
                            card, card
                        };
                        huCard.Add(hucard);
                    }

                    return(true);
                }

                // 十三幺
                if ((from card in Hand_Cards where card.yao9 == true select card).Count() == 14)
                {
                    // 将要和的牌加入和牌牌组以便计算番役
                    cards = from card in Hand_Cards group card by card.name into z where z.Count() == 1 select z.First();

                    if (cards.Count() == 12)
                    {
                        HuCard hucard = new HuCard()
                        {
                            furu  = false,
                            type  = HuCardType.Yao13,
                            cards = new List <MahjongCard>(Hand_Cards)
                        };
                        huCard.Add(hucard);
                        return(true);
                    }
                }
            }

            // 排序手牌
            hand_cards.Sort((MahjongCard n1, MahjongCard n2) => n1.name.CompareTo(n2.name));

            // 寻找所有的雀头,并将其剩下的牌放入列表
            // 遍历所有的牌 (只遍历到最后一张牌的前一张)
            for (int i = 0; i < hand_cards.Count - 1; i++)
            {
                List <MahjongCard>        hu_cards = new List <MahjongCard>(hand_cards);
                IEnumerable <MahjongCard> finch    = from card in hand_cards where card.name == hand_cards[i].name select card;

                // 如果有两张以上重复,则判定为雀头
                if (finch.Count() >= 2)
                {
                    // 清空和牌牌组以便计算番役
                    huCard.Clear();

                    // 将雀头加入牌组
                    HuCard hucard = new HuCard()
                    {
                        type  = HuCardType.Finch,
                        furu  = false,
                        cards = new List <MahjongCard>()
                        {
                            hand_cards[i], hand_cards[i + 1]
                        },
                    };
                    huCard.Add(hucard);

                    // 把雀头从手牌单独出来
                    hu_cards.RemoveAt(i);
                    hu_cards.RemoveAt(i);

                    // 避免重复,跳过同种的其他牌
                    i += finch.Count() - 1;

                    // 判断和牌
                    if (isHu(hu_cards, ref huCard))
                    {
                        // 将副露区的牌加入和牌牌组
                        foreach (MahjongCardFuru furu in Furu_Cards)
                        {
                            HuCard hu = new HuCard
                            {
                                furu  = true,
                                cards = new List <MahjongCard>(furu.cards),
                            };
                            switch (furu.type)
                            {
                            case FuruType.ChiGrade:
                                hu.type = HuCardType.GradeChi;
                                break;

                            case FuruType.ChiSquad:
                                hu.type = HuCardType.SquadChi;
                                break;

                            case FuruType.Pong:
                            case FuruType.Kong_Add:
                            case FuruType.Kong:
                                hu.type = HuCardType.PongKong;
                                break;

                            case FuruType.Kong_Self:     // 暗杠不破坏门前清
                                hu.furu = false;
                                hu.type = HuCardType.PongKong;
                                break;
                            }
                            huCard.Add(hu);
                        }

                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #2
0
        /// <summary>
        ///  和牌判定(除去雀头和副露)
        /// </summary>
        /// <param name="cards">手牌</param>
        /// <param name="start">从第几张手牌开始找刻子</param>
        /// <returns>是否和牌</returns>
        private bool isHu(List <MahjongCard> cards, int start, ref List <HuCard> huCard)
        {
            if (cards.Count == 0)
            {
                return(true); // 空牌和
            }

            if (cards.Count < 3)
            {
                return(false); // 剩牌不和
            }

            // 针对第一张牌开始寻找刻子和顺子
            IEnumerable <MahjongCard> u = from card in cards where card.name == cards[start].name select card;
            int count = u.Count();

            if (count >= 3)
            {
                // 将刻子加入牌组
                HuCard hucard = new HuCard()
                {
                    type  = HuCardType.PongKong,
                    furu  = false,
                    cards = new List <MahjongCard>()
                    {
                        cards[start], cards[start + 1], cards[start + 2]
                    },
                };
                huCard.Add(hucard);

                // 删除这个刻子
                for (int m = 0; m < 3; m++)
                {
                    cards.RemoveAt(start);
                }

                // 递归判和
                return(isHu(cards, ref huCard));
            }
            else
            {
                if (start + 1 < cards.Count)
                {
                    return(isHu(cards, start + 1, ref huCard));
                }
                else
                {
                    // 寻找顺子(年级和小组顺子)
                    MahjongCard cur_card = u.First();

                    // 获得牌种
                    MahjongCardType type = cur_card.type;

                    // 只有角色牌才可以凑成年级或小组顺子
                    if (type == MahjongCardType.Char)
                    {
                        // 获得团体、年级和小组信息
                        MahjongCardGroupType group = cur_card.group;
                        MahjongCardGradeType grade = cur_card.grade;
                        MahjongCardSquadType squad = cur_card.squad;

                        // 确认同团体的牌有至少三张
                        IEnumerable <MahjongCard> same_group = from card in cards where (card.name != cur_card.name) && (card.@group == @group) && (card.type == MahjongCardType.Char) select card;
                        if (same_group.Count() >= 2)
                        {
                            // 判断同年级/同小组
                            IEnumerable <MahjongCard> same_grade = from card in same_group where card.grade == grade select card;
                            IEnumerable <MahjongCard> same_squad = from card in same_group where card.squad == squad select card;
                            IEnumerable <MahjongCard> determine;

                            bool GradeOrSquad = false;
                            if (same_grade.Count() >= 2)
                            {
                                GradeOrSquad = false;
                                determine    = same_grade;         // 判断同年级
                            }
                            else if (same_squad.Count() >= 2)
                            {
                                GradeOrSquad = true;
                                determine    = same_squad; // 判断同小队
                            }
                            else
                            {
                                return(false);
                            }

                            // 每种牌只找出一张
                            IEnumerable <MahjongCard> not_same = from card in determine group card by card.name into g select g.First();

                            if (not_same.Count() >= 2)
                            {
                                MahjongCard[] not_same_cards = not_same.ToArray();

                                // 将顺子加入牌组
                                HuCard hucard = new HuCard()
                                {
                                    type  = (GradeOrSquad) ? HuCardType.SquadChi : HuCardType.GradeChi,
                                    furu  = false,
                                    cards = new List <MahjongCard>()
                                    {
                                        cur_card, not_same_cards[0], not_same_cards[1]
                                    },
                                };
                                huCard.Add(hucard);

                                // 从手牌中删除
                                bool p = true, q = true, r = true; // 防止重复删除
                                for (int i = 0; i < cards.Count; i++)
                                {
                                    if ((cards[i].name == cur_card.name) && p)
                                    {
                                        p = false; cards.RemoveAt(i); i--; continue;
                                    }
                                    if ((cards[i].name == not_same_cards[0].name) && q)
                                    {
                                        q = false; cards.RemoveAt(i); i--; continue;
                                    }
                                    if ((cards[i].name == not_same_cards[1].name) && r)
                                    {
                                        r = false; cards.RemoveAt(i); i--; continue;
                                    }
                                    if (!(p || q || r))
                                    {
                                        break;
                                    }
                                }

                                // 递归判和
                                return(isHu(cards, ref huCard));
                            }
                        }
                    }
                }

                return(false);
            }
        }