/// <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); }
/// <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); } }