/// <summary> /// 找连对 /// </summary> /// <param name="cdSplitStruct"></param> /// <returns></returns> public int[] FindType2Abc(CdSplitStruct cdSplitStruct) { var len = cdSplitStruct.DuiCds.Count + cdSplitStruct.ThreeCds.Count; if (len < 3) { return(null); } var allpossbCds = new List <int>(); allpossbCds.AddRange(cdSplitStruct.DuiCds); allpossbCds.AddRange(cdSplitStruct.ThreeCds); var canLianduiCds = CheckShun(allpossbCds.ToArray(), 3); canLianduiCds = RemoveBigCdsInArray(canLianduiCds); if (canLianduiCds == null || canLianduiCds.Length < 3) { return(null); } var typ2AbcList = new List <int>(); foreach (var cd in canLianduiCds) { typ2AbcList.Add(cd); typ2AbcList.Add(cd); } return(typ2AbcList.ToArray()); }
/// <summary> /// 找顺子 /// </summary> /// <param name="cdSplitStruct"></param> /// <returns></returns> public int[] FindType123(CdSplitStruct cdSplitStruct) { var len = cdSplitStruct.DanCds.Count + cdSplitStruct.DuiCds.Count + cdSplitStruct.ThreeCds.Count + cdSplitStruct.FourCds.Count; if (len < 5) { return(null); } var allPossbCds = new List <int>(); allPossbCds.AddRange(cdSplitStruct.DanCds); allPossbCds.AddRange(cdSplitStruct.DuiCds); allPossbCds.AddRange(cdSplitStruct.ThreeCds); allPossbCds.AddRange(cdSplitStruct.FourCds); var danshun = CheckShun(allPossbCds.ToArray(), 5); danshun = RemoveBigCdsInArray(danshun); if (danshun == null || danshun.Length < 5) { return(null); } return(danshun); }
/// <summary> /// 智能选牌 在某个范围内 选出 除了单 和对子 之外的牌型 /// </summary> private int[] CheckOutWithOutType1And2(CdSplitStruct cdsplitStruct) { //找飞机 var feiji = FindFeiJi(cdsplitStruct); if (feiji != null) { return(feiji); } #region 连对 顺子找长度比较长的牌 var cdsList = new List <int[]>(); //找连对, var lianDui = FindType2Abc(cdsplitStruct); cdsList.Add(lianDui); //找顺子, var shunzi = FindType123(cdsplitStruct); cdsList.Add(shunzi); //找3带, var typ3TakeCds = FindType3TakeCds(cdsplitStruct); cdsList.Add(typ3TakeCds); int[] chooseCds = null; foreach (var cds in cdsList) { if (chooseCds == null) { chooseCds = cds; } else { if (cds != null && cds.Length > chooseCds.Length) { chooseCds = cds; } } } if (chooseCds != null && chooseCds.Length > 0) { return(chooseCds); } #endregion //找4带2 var type42Cds = FindType42Cds(cdsplitStruct); if (type42Cds != null) { return(type42Cds); } //找炸弹 var bomb = FindBomb(cdsplitStruct); return(bomb); }
/// <summary> /// 找单 /// </summary> /// <param name="cdSplitStruct"></param> /// <returns></returns> public int[] FindType1(CdSplitStruct cdSplitStruct) { var sotedCds = cdSplitStruct.SortedCds; if (sotedCds.Length > 0) { return new[] { sotedCds[0] } } ; return(null); }
//----------------------------------------------------------------end /// <summary> /// 检测出的牌可能组成的顺子 /// </summary> /// <param name="cdsplitStruct"></param> /// <param name="hdSplitSutuct">所有手牌</param> private int[] CheckPossbShunzi(CdSplitStruct cdsplitStruct, CdSplitStruct hdSplitSutuct) { var danCds = cdsplitStruct.DanCds; if (cdsplitStruct.OrgCds.Length != danCds.Count || danCds.Count < 2) { return(null); } //排序好的 框出来的牌 var sortedCds = PokerRuleUtil.GetSortedValues(danCds.ToArray()); var listTemp = new List <int>(); listTemp.AddRange(hdSplitSutuct.DanCds); listTemp.AddRange(hdSplitSutuct.DuiCds); listTemp.AddRange(hdSplitSutuct.ThreeCds); listTemp.AddRange(hdSplitSutuct.FourCds); var keys = listTemp.ToArray(); var allposbShunList = PokerRuleUtil.GetAllPossibleShun(keys, 5); if (allposbShunList == null || allposbShunList.Count < 1) { return(null); } //存手牌中最终找到的那组顺牌 var findShun = new List <int>(); foreach (var shunCds in allposbShunList) { var shuncdsLen = shunCds.Length; if (shuncdsLen >= 5) { if (shunCds[0] <= sortedCds[0] && shunCds[shuncdsLen - 1] >= sortedCds[sortedCds.Length - 1]) { findShun.Clear(); findShun.AddRange(shunCds); break; } } } if (findShun.Count < 1) { return(null); } return(findShun.ToArray()); }
/// <summary> /// 找3带 /// </summary> /// <param name="cdSplitStruct"></param> /// <returns></returns> public int[] FindType3TakeCds(CdSplitStruct cdSplitStruct) { var sortedCd = cdSplitStruct.SortedCds; var sortedCdLen = sortedCd.Length; var threeCds = cdSplitStruct.ThreeCds; if (threeCds.Count < 1 || sortedCdLen < 4) { return(null); } var typ3TakeCds = new List <int>(); typ3TakeCds.AddRange(new [] { threeCds[0], threeCds[0], threeCds[0] }); //先找三代单牌 var danCds = cdSplitStruct.DanCds; if (danCds.Count > 0) { typ3TakeCds.Add(danCds[0]); return(typ3TakeCds.ToArray()); } //再找三代对牌 var duicds = cdSplitStruct.DuiCds; if (danCds.Count > 0) { typ3TakeCds.Add(duicds[0]); typ3TakeCds.Add(duicds[0]); return(typ3TakeCds.ToArray()); } //以上找不到,就从牌值最小的牌开始找 for (int i = 0; i < sortedCdLen; i++) { if (threeCds[0] != sortedCd[i]) { typ3TakeCds.Add(sortedCd[i]); return(typ3TakeCds.ToArray()); } } return(null); }
/// <summary> /// 检测潜在的三带的牌 /// </summary> /// <param name="cdsplitStruct"> 已经被弹起的牌值的数据结构</param> /// <param name="hdSplitSutuct"> 手牌</param> /// <returns></returns> private int[] CheckThreeWith(CdSplitStruct cdsplitStruct, CdSplitStruct hdSplitSutuct) { var danList = cdsplitStruct.DanCds; var duiList = cdsplitStruct.DuiCds; var sanList = hdSplitSutuct.ThreeCds; foreach (var v in sanList) { int value = v; if (value < PokerRuleUtil.SmallJoker) { value &= 0xf; } if (danList.Contains(value) || duiList.Contains(value)) { var orderCds = cdsplitStruct.OrderSortedCds; var otherCds = new List <int>(); for (int i = 0; i < orderCds.Length; i++) { if (orderCds[i] != value) { otherCds.Add(orderCds[i]); } } //组合一下牌变成wholecards otherCds.AddRange(new [] { value, value, value }); if (_getCdsType != null) { int[] cds = otherCds.ToArray(); cds = PokerRuleUtil.GetSortedValues(cds); var type = _getCdsType(cds); //如果有合法牌返回这组牌 if (type > 0) { return(otherCds.ToArray()); } } } } return(null); }
/// <summary> /// 在一组牌中找到炸弹牌型的子集 /// </summary> /// <param name="cdSplitStruct"></param> /// <returns></returns> public int[] FindBomb(CdSplitStruct cdSplitStruct) { var cdsLen = cdSplitStruct.OrgCds.Length; if (cdsLen < 4) { return(null); } var fourCds = cdSplitStruct.FourCds; if (fourCds.Count < 1) { return(null); } return(new[] { fourCds[0], fourCds[0], fourCds[0], fourCds[0] }); }
/// <summary> /// 找对 /// </summary> /// <param name="cdSplitStruct"></param> /// <returns></returns> public int[] FindType2(CdSplitStruct cdSplitStruct) { if (cdSplitStruct.DuiCds.Count > 0) { return new[] { cdSplitStruct.DuiCds[0], cdSplitStruct.DuiCds[0] } } ; if (cdSplitStruct.ThreeCds.Count > 0) { return new[] { cdSplitStruct.ThreeCds[0], cdSplitStruct.ThreeCds[0] } } ; if (cdSplitStruct.FourCds.Count > 0) { return new[] { cdSplitStruct.FourCds[0], cdSplitStruct.FourCds[0] } } ; return(null); }
//-----------------对外智能选牌使用的方法 /// <summary> /// 在不需要比较别家出牌,自己先手出牌的情况下 /// </summary> /// <param name="selectCds">玩家从手牌中提出的牌</param> /// <param name="handCds">手牌</param> /// <returns></returns> public int[] GetcdsWithOutCompare(int[] selectCds, int[] handCds) { //在框选的范围内找合法的牌,不考虑 对子和单牌的情况 var selcdtype = _getCdsType(selectCds); //如果直接是合法牌,则直接返回框选的牌 if (selcdtype != CardType.None && selcdtype != CardType.Exception)//&& selcdtype != CardType.C1 && selcdtype != CardType.C2 { return(selectCds); } var cdsplitStruct = new CdSplitStruct(selectCds); var canoutCds = CheckOutWithOutType1And2(cdsplitStruct); if (canoutCds != null && canoutCds.Length > 0) { return(canoutCds); } //所有手牌的struct var hdSplitSutuct = new CdSplitStruct(handCds); var posbShun = CheckPossbShunzi(cdsplitStruct, hdSplitSutuct); if (posbShun != null) { return(posbShun); } var posbLd = CheckpossbLianDui(cdsplitStruct, hdSplitSutuct); if (posbLd != null) { return(posbLd); } var posbSanTake = CheckThreeWith(cdsplitStruct, hdSplitSutuct); return(posbSanTake); }
/// <summary> /// 直接比较两组牌 /// </summary> /// <param name="outCds">本次出的牌</param> /// <param name="lastOutCds">要被管的牌</param> /// <returns>true为出的牌能管上,反之false</returns> public static bool JustCompareCds(int[] outCds, int[] lastOutCds) { if (outCds == null) { throw new Exception("JustCompareCds: outcds为空"); } if (lastOutCds == null) { throw new Exception("JustCompareCds: lastOutCds为空"); } var otCdstype = GetCdsType(outCds); if (otCdstype == CardType.Exception || otCdstype == CardType.None) { return(false); } if (otCdstype == CardType.C42) { return(true); } var lastOtCdsType = GetCdsType(lastOutCds); if (otCdstype == lastOtCdsType) { if (outCds.Length != lastOutCds.Length) { return(false); } switch (otCdstype) { case CardType.C1: return(JustCompareMinValue(outCds, lastOutCds)); case CardType.C2: return(JustCompareMinValue(outCds, lastOutCds)); case CardType.C3: return(JustCompareMinValue(outCds, lastOutCds)); case CardType.C4: return(JustCompareMinValue(outCds, lastOutCds)); case CardType.C5: return(JustCompareMinValue(outCds, lastOutCds)); case CardType.C123: return(JustCompareMinValue(outCds, lastOutCds)); case CardType.C1122: return(JustCompareMinValue(outCds, lastOutCds)); case CardType.C111222: return(JustCompareMinValue(outCds, lastOutCds)); } var outcdsSplit = new CdSplitStruct(outCds); var lastOutcdsSplit = new CdSplitStruct(lastOutCds); switch (otCdstype) { case CardType.C31: return(outcdsSplit.ThreeCds[0] > lastOutcdsSplit.ThreeCds[0]); case CardType.C32: return(outcdsSplit.ThreeCds[0] > lastOutcdsSplit.ThreeCds[0]); case CardType.C11122234: return(outcdsSplit.ThreeCds[0] > lastOutcdsSplit.ThreeCds[0]); case CardType.C1112223344: return(outcdsSplit.ThreeCds[0] > lastOutcdsSplit.ThreeCds[0]); case CardType.C411: return(outcdsSplit.FourCds[0] > lastOutcdsSplit.FourCds[0]); } } else { if (lastOtCdsType == CardType.C42) { return(false); } switch (otCdstype) { case CardType.C4: { return(lastOtCdsType != CardType.C5); } case CardType.C5: { return(true); } default: return(false); } } //有情况没有考虑到 throw new Exception("两组牌比较时,此方法某种情况没有考虑到"); }
/// <summary> /// 找飞机,三带不算在飞机范围内,最少8张牌算一个飞机 /// </summary> /// <param name="cdSplitStruct"></param> /// <returns></returns> public int[] FindFeiJi(CdSplitStruct cdSplitStruct) { var cdsLen = cdSplitStruct.OrgCds.Length; if (cdsLen < 8) { return(null); } //找3顺 var threeShun = CheckShun(cdSplitStruct.ThreeCds.ToArray(), 2); threeShun = RemoveBigCdsInArray(threeShun); if (threeShun == null || threeShun.Length < 2) { return(null); } //存储顺在一起的3张牌组,未*3 var canLian3Cds = new List <int>(); canLian3Cds.AddRange(threeShun); var threeCdsLen = canLian3Cds.Count; //获取飞机带的部分 var sortedCds = cdSplitStruct.SortedCds; //var threeCdsLenX2 = threeCdsLen * 2; //可组成如果带的部分的牌数不足,则返回null if ((sortedCds.Length - threeCdsLen * 3) < threeCdsLen) { return(null); } //最终选出的牌 var finalCds = new List <int>(); foreach (var cd in canLian3Cds) { finalCds.Add(cd); finalCds.Add(cd); finalCds.Add(cd); } //先找可能三带单的飞机 var dancds = cdSplitStruct.DanCds; if (dancds.Count >= threeCdsLen) { for (int i = 0; i < threeCdsLen; i++) { finalCds.Add(dancds[i]); } return(finalCds.ToArray()); } //再找可能是三代对牌 var duiCds = cdSplitStruct.DuiCds; if (duiCds.Count >= threeCdsLen) { for (int i = 0; i < threeCdsLen; i++) { finalCds.Add(duiCds[i]); finalCds.Add(duiCds[i]); } return(finalCds.ToArray()); } //记录带的部分的个数 int addI = 0; for (int i = 0; i < sortedCds.Length; i++) { if (!canLian3Cds.Contains(sortedCds[i])) { finalCds.Add(sortedCds[i]); addI++; if (addI == threeCdsLen) { break; } } } return(finalCds.ToArray()); }
/* * /// <summary> * /// 把一组牌 单张 对子,三张,4张 分组,每组是排序好的 * /// </summary> * public struct CdSplitStruct * { * /// <summary> * /// 原始卡牌组数据,没有经过花色过滤 * /// </summary> * public readonly int[] OrgCds; * /// <summary> * /// 按照 单张,对子 3张 4张 顺序 排列的牌组 * /// </summary> * public readonly int[] SortedCds; * //以从小到大顺序排列的牌组 * public readonly int[] OrderSortedCds; * /// <summary> * /// 单牌组 * /// </summary> * public readonly List<int> DanCds; * /// <summary> * /// 对牌组,只存牌值 * /// </summary> * public readonly List<int> DuiCds; * /// <summary> * /// 3牌组,只存牌值 * /// </summary> * public readonly List<int> ThreeCds; * /// <summary> * /// 4牌组,只存牌值 * /// </summary> * public readonly List<int> FourCds; * * public CdSplitStruct(int[] cards) * { * OrgCds = (int[])cards.Clone(); * * DanCds = new List<int>(); * DuiCds = new List<int>(); * ThreeCds = new List<int>(); * FourCds = new List<int>(); * * if (cards == null) throw new Exception("CdSplitStruct 生成错误 cards为null"); * * OrderSortedCds = GetSortedValues(cards); * * var cdsDic = new Dictionary<int, short>(); //牌值 ,个数 * * for (int i = 0; i < OrderSortedCds.Length; i++) * { * if (!cdsDic.ContainsKey(OrderSortedCds[i])) * { * cdsDic[OrderSortedCds[i]] = 1; * continue; * } * * cdsDic[OrderSortedCds[i]] += 1; * } * * foreach (var key in cdsDic.Keys) * { * switch (cdsDic[key]) * { * case 1: * DanCds.Add(key); * break; * case 2: * DuiCds.Add(key); * break; * case 3: * ThreeCds.Add(key); * break; * case 4: * FourCds.Add(key); * break; * } * } * * SortedCds = new int[DanCds.Count + DuiCds.Count * 2 + ThreeCds.Count * 3 + FourCds.Count * 4]; * int sortedI = 0; * foreach (var cd in DanCds) * { * SortedCds[sortedI] = cd; * sortedI++; * } * foreach (var cd in DuiCds) * { * SortedCds[sortedI] = cd; * sortedI++; * SortedCds[sortedI] = cd; * sortedI++; * } * foreach (var cd in ThreeCds) * { * SortedCds[sortedI] = cd; * sortedI++; * SortedCds[sortedI] = cd; * sortedI++; * SortedCds[sortedI] = cd; * sortedI++; * } * foreach (var cd in FourCds) * { * SortedCds[sortedI] = cd; * sortedI++; * SortedCds[sortedI] = cd; * sortedI++; * SortedCds[sortedI] = cd; * sortedI++; * SortedCds[sortedI] = cd; * sortedI++; * } * } * } */ /// <summary> /// 在一组牌中找到4带2牌型的子集 /// </summary> /// <param name="cdSplitStruct">卡牌组</param> public int[] FindType42Cds(CdSplitStruct cdSplitStruct) { var cdsLen = cdSplitStruct.OrgCds.Length; if (cdsLen < 6) { return(null); } var fourCds = cdSplitStruct.FourCds; if (fourCds.Count < 1) { return(null); } //type42牌型list var type42CdsList = new List <int>(); for (int i = 0; i < 4; i++) { type42CdsList.Add(fourCds[0]); } //先找4带2单的可能 var dancds = cdSplitStruct.DanCds; if (dancds.Count > 1) { for (int i = 0; i < 2; i++) { type42CdsList.Add(dancds[i]); } return(type42CdsList.ToArray()); } //再找4带2对的可能 var duiCds = cdSplitStruct.DuiCds; if (duiCds.Count > 1) { for (int i = 0; i < 2; i++) { type42CdsList.Add(duiCds[i]); type42CdsList.Add(duiCds[i]); } return(type42CdsList.ToArray()); } //再找4带1对的可能 if (duiCds.Count == 1) { type42CdsList.Add(duiCds[0]); type42CdsList.Add(duiCds[0]); return(type42CdsList.ToArray()); } //4带2的2那部分 var compcdsPartof2 = new List <int>(); compcdsPartof2.AddRange(cdSplitStruct.DanCds); foreach (var i in cdSplitStruct.DuiCds) { compcdsPartof2.Add(i); compcdsPartof2.Add(i); } foreach (var i in cdSplitStruct.ThreeCds) { compcdsPartof2.Add(i); compcdsPartof2.Add(i); compcdsPartof2.Add(i); } if (compcdsPartof2.Count < 2) { return(null); } for (int i = 0; i < 2; i++) { type42CdsList.Add(compcdsPartof2[i]); } return(type42CdsList.ToArray()); }
/// <summary> /// 检测出牌可能组成的连对 /// </summary> /// <param name="cdsplitStruct"></param> /// <param name="hdSplitSutuct"></param> /// <returns></returns> private int[] CheckpossbLianDui(CdSplitStruct cdsplitStruct, CdSplitStruct hdSplitSutuct) { var danCds = cdsplitStruct.DanCds; var duiCds = cdsplitStruct.DuiCds; if (cdsplitStruct.OrgCds.Length != danCds.Count + duiCds.Count * 2 || (danCds.Count + duiCds.Count) < 2) { return(null); } var chooseCdsValueList = new List <int>(); chooseCdsValueList.AddRange(danCds); chooseCdsValueList.AddRange(duiCds); chooseCdsValueList.Sort(); //存手牌中对牌的值列表 var allduiHandCdValue = hdSplitSutuct.DuiCds; //框选出的牌 var chooseCds = chooseCdsValueList.ToArray(); //所有可能的连对 组 var alposbLdList = PokerRuleUtil.GetAllPossibleShun(allduiHandCdValue.ToArray(), 3); if (alposbLdList == null || alposbLdList.Count < 1) { return(null); //没有找到符合条件的连对 } var findLd = new List <int>(); foreach (var ldCds in alposbLdList) { var ldLen = ldCds.Length; if (ldLen >= 3) { if (ldCds[0] <= chooseCds[0] && ldCds[ldCds.Length - 1] >= chooseCds[chooseCds.Length - 1]) { findLd.Clear(); findLd.AddRange(ldCds); break; } } } if (findLd.Count < 1) { return(null); //没有找到符合条件的连对 } var findldLen = findLd.Count; var returnLdCds = new int[findldLen * 2]; int j = 0; for (int i = 0; i < findldLen; i++) { returnLdCds[j++] = findLd[i]; returnLdCds[j++] = findLd[i]; } return(returnLdCds); }