Esempio n. 1
0
        /// <summary>
        /// 能够鸣牌计算
        /// </summary>
        private List <FuruAble> isCanFuru()
        {
            // 获得刚刚打牌的玩家的牌河和打出的牌
            List <MahjongCard> played_cards = GetPlayerCardPlayed(Playing);
            MahjongCard        last_played  = played_cards.Last(); // 最后一张

            // 比对其他三家的手牌
            List <FuruAble> furuAbles = new List <FuruAble>();

            // 记录是否有玩家可以碰或者杠以减少不必要的计算
            bool hasPongKong = false;

            // 遍历所有其它玩家
            for (int player = 0; player < 4; player++)
            {
                if (player == Playing)
                {
                    continue; // 跳过自己
                }

                // 获得手牌
                List <MahjongCard> player_hand = GetPlayerCardOnHand(player);

                // 记录可副露牌组
                FuruAble furuAble = new FuruAble(player);

                // 如果已经有别的玩家可以碰杠,则不可能再有玩家可以碰杠
                if (hasPongKong == false)
                {
                    // 优先找出杠子和刻子
                    IEnumerable <MahjongCard> PongKong = from card in player_hand where card == last_played select card;
                    if (PongKong.Count() >= 2)
                    {
                        hasPongKong = true;

                        // 可以碰
                        furuAble.FuruableList.Add(new MahjongCardFuru()
                        {
                            cards  = Enumerable.Repeat(last_played, 2).ToList(),
                            target = Playing,
                            type   = FuruType.Pong,
                        });

                        if (PongKong.Count() == 3)
                        {
                            // 可以杠
                            furuAble.FuruableList.Add(new MahjongCardFuru()
                            {
                                cards  = Enumerable.Repeat(last_played, 3).ToList(),
                                target = Playing,
                                type   = FuruType.Kong,
                            });
                            hasPongKong = true;
                        }
                    }
                }


                if (last_played.type == MahjongCardType.Char)
                {
                    // 年级和小组顺子(吃)
                    // 年级顺子
                    MahjongCardName      name  = last_played.name;
                    MahjongCardGradeType grade = last_played.grade;
                    MahjongCardGroupType group = last_played.group;
                    IEnumerable <IGrouping <MahjongCardName, MahjongCard> > grade_chi = from card in player_hand
                                                                                        where (card.grade == grade) && (card.name != name) &&
                                                                                        (card.type == MahjongCardType.Char) && (card.@group == @group)
                                                                                        group card by card.name into g
                                                                                        select g;
                    if (grade_chi.Count() == 2)
                    {
                        // 至少要有两种同年级的牌才可以吃
                        // 获得要吃的牌
                        List <MahjongCard> chi = new List <MahjongCard>();
                        foreach (IGrouping <MahjongCardName, MahjongCard> cards in grade_chi)
                        {
                            chi.Add(cards.First());
                        }

                        // 加入可副露列表
                        furuAble.FuruableList.Add(new MahjongCardFuru()
                        {
                            cards  = chi,
                            target = Playing,
                            type   = FuruType.ChiGrade,
                        });
                    }

                    // 小组顺子
                    MahjongCardSquadType squad = last_played.squad;
                    IEnumerable <IGrouping <MahjongCardName, MahjongCard> > squad_chi = from card in player_hand
                                                                                        where (card.squad == squad) && (card.name != name) && (card.type == MahjongCardType.Char)
                                                                                        group card by card.name into g
                                                                                        select g;
                    if (squad_chi.Count() == 2)
                    {
                        // 至少要有两种同小组的牌才可以吃
                        // 获得要吃的牌
                        List <MahjongCard> chi = new List <MahjongCard>();
                        foreach (IGrouping <MahjongCardName, MahjongCard> cards in squad_chi)
                        {
                            chi.Add(cards.First());
                        }

                        // 加入可副露列表
                        furuAble.FuruableList.Add(new MahjongCardFuru()
                        {
                            cards  = chi,
                            target = Playing,
                            type   = FuruType.ChiSquad,
                        });
                    }
                }
                furuAbles.Add(furuAble);
            }

            return(furuAbles);
        }
Esempio n. 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);
            }
        }