/// <summary> /// 王炸 /// </summary> /// <param name="cards"></param> /// <param name="result"></param> /// <returns></returns> public static bool CheckJokerBomb(Games game_type, List <CardEnum> cards, out CombineResult result) { var cards_clone = cards.Clone(); result = null; if (game_type.IsMetallic() && cards_clone.Count == 3) { if (cards_clone.Count(c => Jokers.Contains(c)) == 3) { //6星王炸中最小的 result = new CombineResult(Combine.Bomb, 5, cards_clone[0], (byte)cards_clone.Count); return(true); } } else if (cards_clone.Count == 4) { if (cards_clone.Count(c => Jokers.Contains(c)) == 4) { if (game_type.IsMetallic()) { //7星王炸 result = new CombineResult(Combine.Bomb, 7, cards_clone[0], (byte)cards_clone.Count); } else { //传统模式天王炸最大 result = new CombineResult(Combine.Bomb, 8, cards_clone[0], (byte)cards_clone.Count); } return(true); } } return(false); }
/// <summary> /// 炸弹 /// </summary> /// <param name="cards"></param> /// <param name="result"></param> /// <returns></returns> public static bool CheckBomb(Games game_type, List <CardEnum> cards, out CombineResult result) { result = null; var cards_clone = cards.Clone(); if (cards_clone.Count < 4) { return(false); } if (game_type.IsMetallic() && cards_clone.Count() >= 12) { //大于12张牌,连炸可能性比较大,先判断连炸,不是判断普通炸 if (CheckLineBomb(game_type, cards_clone, out result)) { return(true); } } CardEnum base_card = cards_clone[0]; foreach (var card in cards_clone) { if (!(card == base_card || (game_type.IsMetallic() && Jokers.Contains(card)))) { return(false); } } result = new CombineResult(Combine.Bomb, (byte)cards_clone.Count, cards_clone[0], (byte)cards_clone.Count); return(true); }
/// <summary> /// 连炸 /// </summary> /// <param name="game_type"></param> /// <param name="cards"></param> /// <param name="result"></param> /// <returns></returns> public static bool CheckLineBomb(Games game_type, List <CardEnum> cards, out CombineResult result) { result = null; var cards_clone = cards.Clone(); int cards_count = cards_clone.Count(); if (cards_count >= 12) { CardEnum min_card = cards_clone[0]; int joker_count = 0; if (game_type.IsMetallic()) { joker_count = cards_clone.RemoveAll(c => Jokers.Contains(c)); } var card_groups = cards_clone.GroupBy(c => c).ToList(); List <int> bomb_count = new List <int>(); CardEnum next_card = cards_clone[0]; for (int i = 0; i < card_groups.Count; i++) { if (next_card == card_groups[i].First()) { int group_count = card_groups[i].Count(); if (group_count >= 4) { next_card = NextCardNumber(next_card); bomb_count.Add(group_count); } else if (joker_count >= 4 - group_count) { joker_count -= (4 - group_count); next_card = NextCardNumber(next_card); bomb_count.Add(4); } else { return(false); } } else if (joker_count >= 4) { joker_count -= 4; i -= 1; next_card = NextCardNumber(next_card); bomb_count.Add(4); } else { return(false); } } result = new CombineResult(Combine.Bomb, (byte)GetLineBombStar(bomb_count, joker_count), min_card, (byte)cards_count); return(true); } return(false); }
/// <summary> /// 三张 /// </summary> /// <param name="cards"></param> /// <param name="result"></param> /// <returns></returns> public static bool CheckFullHouse(Games game_type, List <CardEnum> cards, out CombineResult result) { result = null; var cards_clone = cards.Clone(); if (cards_clone.Count != 3) { return(false); } if (cards_clone[0] == cards_clone[1] && cards_clone[0] == cards_clone[2]) { result = new CombineResult(Combine.FullHouse, 0, cards_clone[0], (byte)cards_clone.Count); return(true); } if (game_type.IsMetallic()) { //千变规则 int joker_count = cards_clone.Count(c => Jokers.Contains(c)); if (joker_count >= 2 || (joker_count == 1 && cards_clone[0] == cards_clone[1])) { result = new CombineResult(Combine.FullHouse, 0, cards_clone[0], (byte)cards_clone.Count); return(true); } } return(false); }
/// <summary> /// 连对 /// </summary> /// <param name="cards"></param> /// <param name="result"></param> /// <returns></returns> public static bool CheckLinePairs(Games game_type, List <CardEnum> cards, out CombineResult result) { result = null; var cards_clone = cards.Clone(); if (cards_clone.Count >= 6 && cards_clone.Count % 2 == 0) { CardEnum min_card = cards_clone[0]; byte card_count = (byte)cards_clone.Count; int joker_count = 0; if (game_type.IsMetallic()) { joker_count = cards_clone.RemoveAll(c => Jokers.Contains(c)); } int count = cards_clone.Count; CardEnum next_card = cards_clone[0]; for (int i = 0; i < cards_clone.Count; i += 2) { if (i < count && cards_clone[i] == next_card) { if (i + 1 < count && cards_clone[i + 1] == next_card) { next_card = NextCardNumber(next_card); } else if (joker_count >= 1) { --joker_count; --i; next_card = NextCardNumber(next_card); } else { return(false); } } else if (joker_count >= 2) { joker_count -= 2; i -= 2; next_card = NextCardNumber(next_card); } else { return(false); } } result = new CombineResult(Combine.LinePairs, 0, min_card, card_count); return(true); } return(false); }
/// <summary> /// 选可以出的牌 /// </summary> /// <param name="cards"></param> /// <param name="result"></param> /// <returns></returns> public static List <byte> ChooseCard(Games game_type, List <byte> cards, List <byte> pre_discard_cards, bool isPartner = false) { if (pre_discard_cards == null) { return(ChooseCard(game_type, cards)); } List <CombineResult> results = null; if (game_type.IsMetallic()) { results = TwillLogic.CheckCombines(pre_discard_cards); } else { results = new List <CombineResult>() { TwillLogic.CheckCombine(pre_discard_cards) }; } foreach (var result in results) { var hand_cards = cards.ConvertToNumber(); var hand_cards_clone = hand_cards.Clone(); List <CardEnum> combine_cards = null; if (result.combine != Combine.Bomb) { var bombs = RemoveBombs(hand_cards); //移除炸弹 combine_cards = FindCombine(game_type, hand_cards, result); //获取符合条件牌组 if (combine_cards != null) { return(GetCards(cards, hand_cards_clone, combine_cards)); //转换为具体的牌 } } //不对对家使用炸弹 if (isPartner) { return(null); } //找炸弹 combine_cards = FindBomb(game_type, hand_cards_clone, result); return(GetCards(cards, hand_cards_clone, combine_cards)); //转换为具体的牌 } return(null); }
/// <summary> /// 一对 /// </summary> /// <param name="cards"></param> /// <param name="result"></param> /// <returns></returns> public static bool CheckOnePairs(Games game_type, List <CardEnum> cards, out CombineResult result) { result = null; var cards_clone = cards.Clone(); if (cards_clone.Count == 2 && (cards_clone[0] == cards_clone[1] || (game_type.IsMetallic() && cards_clone.Exists(c => Jokers.Contains(c)) //千变时只要存在大小王都可以算对子 ))) { result = new CombineResult(Combine.OnePairs, 0, cards_clone[0], (byte)cards_clone.Count); return(true); } return(false); }
/// <summary> /// 顺子 /// </summary> /// <param name="cards"></param> /// <param name="result"></param> /// <returns></returns> public static bool CheckStraight(Games game_type, List <CardEnum> cards, out CombineResult result) { result = null; var cards_clone = cards.Clone(); if (cards_clone.Count >= 5) { CardEnum min_card = cards_clone[0]; byte card_count = (byte)cards_clone.Count; int joker_count = 0; if (game_type.IsMetallic()) { joker_count = cards_clone.RemoveAll(c => Jokers.Contains(c)); } CardEnum next_card = cards_clone[0]; for (int i = 0; i < cards_clone.Count; i++) { if (cards_clone[i] == next_card) { next_card = NextCardNumber(next_card); } else if (joker_count >= 1) { joker_count -= 1; i -= 1; next_card = NextCardNumber(next_card); } else { return(false); } } result = new CombineResult(Combine.Straight, 0, min_card, card_count); return(true); } return(false); }
/// <summary> /// 找炸弹 /// </summary> /// <param name="hand_cards"></param> /// <param name="result"></param> /// <returns></returns> private static List <CardEnum> FindBomb(Games game_type, List <CardEnum> hand_cards, CombineResult result) { var hand_cards_clone = hand_cards.Clone(); List <CardEnum> jokers = new List <CardEnum>(); if (game_type.IsMetallic()) { jokers = hand_cards_clone.FindAll(c => c == CardEnum.LittleJoker || c == CardEnum.ElderJoker); hand_cards_clone.RemoveAll(c => c == CardEnum.LittleJoker || c == CardEnum.ElderJoker); } var group_cards = hand_cards_clone.GroupBy(c => c).OrderBy(c => c.Count()); foreach (var group_card in group_cards) { if (group_card.Count() >= 4) { if (result.combine == Combine.Bomb) { //符合条件的炸弹 if (group_card.Count() > result.card_num || (group_card.Count() == result.card_num && group_card.Key > result.min_card)) { //符合条件炸弹 return(group_card.ToList()); } } else { //炸弹就行 return(group_card.ToList()); } } } if (game_type.IsMetallic()) { foreach (var group_card in group_cards) { if (group_card.Count() + jokers.Count() >= 4) { if (result.combine == Combine.Bomb) { if (group_card.Count() + jokers.Count() >= result.card_num && group_card.Key > result.min_card) { //同星级炸弹,牌比较大 var cards = group_card.ToList(); cards.AddRange(jokers.GetRange(0, result.card_num - group_card.Count())); return(cards); } else if (group_card.Count() + jokers.Count() > result.card_num) { //升一个星级 var cards = group_card.ToList(); cards.AddRange(jokers.GetRange(0, result.card_num - group_card.Count() + 1)); return(cards); } } else { //炸弹就行 var cards = group_card.ToList(); cards.AddRange(jokers.GetRange(0, 4 - group_card.Count())); return(cards); } } } } return(null); }
/// <summary> /// 找适合的组合 /// </summary> /// <param name="hand_cards"></param> /// <param name="result"></param> /// <returns></returns> private static List <CardEnum> FindCombine(Games game_type, List <CardEnum> hand_cards, CombineResult result) { var hand_cards_clone = hand_cards.Clone(); List <CardEnum> useful_cards = new List <CardEnum>(); List <CardEnum> jokers = new List <CardEnum>(); if (game_type.IsMetallic()) { jokers = hand_cards.FindAll(c => c == CardEnum.LittleJoker || c == CardEnum.ElderJoker); hand_cards_clone.RemoveAll(c => c == CardEnum.LittleJoker || c == CardEnum.ElderJoker); } foreach (var item in hand_cards_clone.FindAll(c => c > result.min_card).GroupBy(c => c)) { switch (result.combine) { case Combine.Bridge: //一张 if (item.Count() == 1) { useful_cards.AddRange(item); } break; case Combine.OnePairs: //一对 if (item.Count() == 2) { useful_cards.AddRange(item); } break; case Combine.LinePairs: //连对 if (item.Count() >= 2) { useful_cards.AddRange(item); } break; case Combine.FullHouse: //三张 if (item.Count() >= 3) { useful_cards.AddRange(item); } break; case Combine.LineFullHouse: //连三张 if (item.Count() >= 3) { useful_cards.AddRange(item); } break; case Combine.Straight: //顺子 if (item.Count() == 1) { useful_cards.AddRange(item); } break; } } //第一遍,去除大小王,选最佳匹配方式 if (useful_cards.Count < result.card_num) { //牌数量不够的情况下,直接加上大小王做匹配 useful_cards.AddRange(jokers); useful_cards = useful_cards.FindAll(c => c > result.min_card); if (useful_cards.Count < result.card_num) { goto ReCheck; } } var cards = CheckCombine(game_type, useful_cards, result); if (cards != null) { return(cards); } //第二遍,所有符合条件牌都加上 ReCheck: useful_cards = hand_cards.FindAll(c => c > result.min_card); if (useful_cards.Count < result.card_num) { return(null); } return(CheckCombine(game_type, useful_cards, result)); }