/src/BetGame.DDZ/Utils.cs

https://github.com/2881099/FightLandlord · C# · 634 lines · 576 code · 28 blank · 30 comment · 588 complexity · 636d08d06b67e73955149d47b07a3e9b MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace BetGame.DDZ {
  5. public class Utils {
  6. private static readonly string[] allpokertexts = "🃃,🃓,🂳,🂣,🃄,🃔,🂴,🂤,🃅,🃕,🂵,🂥,🃆,🃖,🂶,🂦,🃇,🃗,🂷,🂧,🃈,🃘,🂸,🂨,🃉,🃙,🂹,🂩,🃊,🃚,🂺,🂪,🃋,🃛,🂻,🂫,🃍,🃝,🂽,🂭,🃎,🃞,🂾,🂮,🃁,🃑,🂱,🂡,🃂,🃒,🂲,🂢,🃟,🂿,🂠".Split(',');
  7. /// <summary>
  8. /// 获取一副新牌
  9. /// </summary>
  10. /// <returns></returns>
  11. internal static List<int> GetNewPoker() {
  12. var list = new List<int>();
  13. for (int a = 0; a < 54; a++) list.Add(a);
  14. return list;
  15. }
  16. /// <summary>
  17. /// 判断是否连续
  18. /// </summary>
  19. /// <param name="poker">使用前请先排序</param>
  20. /// <returns></returns>
  21. public static bool IsSeries(IEnumerable<int> poker) {
  22. if (poker == null || poker.Any() == false) return false;
  23. poker = poker.OrderBy(a => a);
  24. if (poker.Last() >= 15) return false;
  25. int pp = 255;
  26. foreach (var p in poker) {
  27. if (pp != 255 && (
  28. p - pp != 1
  29. )) return false;
  30. pp = p;
  31. }
  32. return true;
  33. }
  34. /// <summary>
  35. /// 获取扑克牌文本
  36. /// </summary>
  37. /// <param name="poker"></param>
  38. /// <returns></returns>
  39. public static string[] GetPokerText(IEnumerable<int> poker) {
  40. var sb = new List<string>();
  41. foreach (var p in poker)
  42. sb.Add(allpokertexts[p < 0 || p > 53 ? allpokertexts.Length - 1 : p]);
  43. return sb.ToArray();
  44. }
  45. internal static HandPokerComplieResult GetHandPokerComplieResult(HandPokerType type, IEnumerable<GroupByPokerResult> gb) {
  46. if (type == HandPokerType. ||
  47. type == HandPokerType. ||
  48. type == HandPokerType.三条) {
  49. var pk = gb.First().poker.OrderByDescending(a => a).ToArray();
  50. return new HandPokerComplieResult { type = type, compareValue = gb.First().key, value = pk, text = GetPokerText(pk) };
  51. }
  52. if (type == HandPokerType.三条带一个) {
  53. var gb3 = gb.Where(a => a.count == 3).First();
  54. var gb1 = gb.Where(a => a.count == 1).First();
  55. var value = gb3.poker.OrderByDescending(a => a).Concat(gb1.poker).ToArray();
  56. return new HandPokerComplieResult { type = type, compareValue = gb3.key, value = value, text = GetPokerText(value) };
  57. }
  58. if (type == HandPokerType.三条带一对) {
  59. var gb3 = gb.Where(a => a.count == 3).First();
  60. var gb2 = gb.Where(a => a.count == 2).First();
  61. var value = gb3.poker.OrderByDescending(a => a).Concat(gb2.poker.OrderByDescending(a => a)).ToArray();
  62. return new HandPokerComplieResult { type = type, compareValue = gb3.key, value = value, text = GetPokerText(value) };
  63. }
  64. if (type == HandPokerType.顺子) {
  65. var gbs = gb.OrderBy(a => a.key);
  66. var value = gbs.Select(a => a.poker.First()).ToArray();
  67. return new HandPokerComplieResult { type = type, compareValue = gbs.Last().key, value = value, text = GetPokerText(value) };
  68. }
  69. if (type == HandPokerType.连对 ||
  70. type == HandPokerType.飞机) {
  71. var gbs = gb.OrderBy(a => a.key);
  72. var tmp = new List<int>();
  73. int cv = 0;
  74. foreach (var g in gb) {
  75. var gpk = g.poker.OrderByDescending(a => a);
  76. tmp.AddRange(gpk);
  77. cv = g.key;
  78. }
  79. var value = tmp.ToArray();
  80. return new HandPokerComplieResult { type = type, compareValue = cv, value = value, text = GetPokerText(value) };
  81. }
  82. if (type == HandPokerType.飞机带N个) {
  83. var gb3 = gb.Where(a => a.count == 3).OrderBy(a => a.key);
  84. var gb1 = gb.Where(a => a.count == 1).OrderBy(a => a.key);
  85. var tmp3 = new List<int>();
  86. int cv = 0;
  87. foreach (var g in gb3) {
  88. var gpk = g.poker.OrderByDescending(a => a);
  89. tmp3.AddRange(gpk);
  90. cv = g.key;
  91. }
  92. var tmp1 = new List<int>();
  93. foreach (var g in gb1) tmp1.Add(g.poker.First());
  94. var value = tmp3.Concat(tmp1).ToArray();
  95. return new HandPokerComplieResult { type = type, compareValue = cv, value = value, text = GetPokerText(value) };
  96. }
  97. if (type == HandPokerType.飞机带N对) {
  98. var gb3 = gb.Where(a => a.count == 3).OrderBy(a => a.key);
  99. var gb2 = gb.Where(a => a.count == 2).OrderBy(a => a.key);
  100. var tmp3 = new List<int>();
  101. int cv = 0;
  102. foreach (var g in gb3) {
  103. var gpk = g.poker.OrderByDescending(a => a);
  104. tmp3.AddRange(g.poker.OrderByDescending(a => a));
  105. cv = g.key;
  106. }
  107. var tmp2 = new List<int>();
  108. foreach (var g in gb2) tmp2.AddRange(g.poker.OrderByDescending(a => a));
  109. var value = tmp3.Concat(tmp2).ToArray();
  110. return new HandPokerComplieResult { type = type, compareValue = cv, value = value, text = GetPokerText(value) };
  111. }
  112. if (type == HandPokerType.炸带二个) {
  113. int cv = 0;
  114. var gb4 = gb.Where(a => a.count == 4);
  115. var gb4len2 = gb4.Any() == false;
  116. if (gb4len2) gb4 = gb.Where(a => a.key == 16 || a.key == 17);
  117. cv = gb4.First().key;
  118. var gb1 = gb4len2 ? gb.Where(a => a.count == 1 && a.key < 16) : gb.Where(a => a.count == 1);
  119. var tmp4 = new List<int>();
  120. foreach (var g in gb4) tmp4.AddRange(g.poker.OrderByDescending(a => a));
  121. var tmp1 = new List<int>();
  122. foreach (var g in gb1) tmp1.AddRange(g.poker);
  123. var value = tmp4.Concat(tmp1).ToArray();
  124. return new HandPokerComplieResult { type = type, compareValue = cv, value = value, text = GetPokerText(value) };
  125. }
  126. if (type == HandPokerType.炸带二对) {
  127. int cv = 0;
  128. var gb4 = gb.Where(a => a.count == 4);
  129. var gb4len2 = gb4.Any() == false;
  130. if (gb4len2) gb4 = gb.Where(a => a.key == 16 || a.key == 17);
  131. cv = gb4.First().key;
  132. var gb2 = gb4len2 ? gb.Where(a => a.count == 1 && a.key < 16) : gb.Where(a => a.count == 2);
  133. var tmp4 = new List<int>();
  134. foreach (var g in gb4) tmp4.AddRange(g.poker.OrderByDescending(a => a));
  135. var tmp2 = new List<int>();
  136. foreach (var g in gb2) tmp2.AddRange(g.poker.OrderByDescending(a => a));
  137. var value = tmp4.Concat(tmp2).ToArray();
  138. return new HandPokerComplieResult { type = type, compareValue = gb4len2 ? tmp4.First() : tmp4.Last(), value = value, text = GetPokerText(value) };
  139. }
  140. if (type == HandPokerType.四条炸 ||
  141. type == HandPokerType.王炸) {
  142. var tmp = new List<int>();
  143. foreach (var g in gb) tmp.AddRange(g.poker.OrderByDescending(a => a));
  144. var value = tmp.ToArray();
  145. return new HandPokerComplieResult { type = type, compareValue = gb.First().key, value = value, text = GetPokerText(value) };
  146. }
  147. throw new ArgumentException("GetHandPokerComplieResult 参数错误");
  148. }
  149. /// <summary>
  150. /// 分组扑克牌
  151. /// </summary>
  152. /// <param name="poker"></param>
  153. /// <returns></returns>
  154. public static IEnumerable<GroupByPokerResult> GroupByPoker(int[] poker) {
  155. if (poker == null || poker.Length == 0) return null;
  156. var dic = new Dictionary<int, GroupByPokerTmpResult>();
  157. for (var a = 0; a < poker.Length; a++) {
  158. int key = 0;
  159. if (poker[a] >= 0 && poker[a] < 52) key = (int)(poker[a] / 4 + 3);
  160. else if (poker[a] == 52) key = 16;
  161. else if (poker[a] == 53) key = 17;
  162. if (key == 0) throw new ArgumentException("poker 参数值错误");
  163. if (dic.ContainsKey(key) == false) dic.Add(key, new GroupByPokerTmpResult());
  164. dic[key].count++;
  165. dic[key].poker.Add(poker[a]);
  166. }
  167. return dic.Select(a => new GroupByPokerResult { key = a.Key, count = a.Value.count, poker = a.Value.poker }).OrderByDescending(a => a.count);
  168. }
  169. /// <summary>
  170. /// 编译一出牌
  171. /// </summary>
  172. /// <param name="gb"></param>
  173. /// <returns></returns>
  174. public static HandPokerComplieResult ComplierHandPoker(IEnumerable<GroupByPokerResult> gb) {
  175. if (gb == null || gb.Any() == false) return null;
  176. var pokerLength = gb.Sum(a => a.count);
  177. if (pokerLength == 1) { //个
  178. return Utils.GetHandPokerComplieResult(HandPokerType., gb);
  179. }
  180. if (pokerLength == 2) { //对,王炸
  181. if (gb.Where(a => a.count == 2).Any()) return Utils.GetHandPokerComplieResult(HandPokerType., gb);
  182. if (gb.Where(a => a.key == 16 || a.key == 17).Any()) return Utils.GetHandPokerComplieResult(HandPokerType.王炸, gb);
  183. }
  184. if (pokerLength == 3) { //三条
  185. if (gb.Where(a => a.count == 3).Any()) return Utils.GetHandPokerComplieResult(HandPokerType.三条, gb);
  186. }
  187. if (pokerLength == 4) { //四条炸,三条带一个,炸带二个
  188. if (gb.Where(a => a.count == 4).Any()) return Utils.GetHandPokerComplieResult(HandPokerType.四条炸, gb);
  189. if (gb.Where(a => a.count == 3).Any()) return Utils.GetHandPokerComplieResult(HandPokerType.三条带一个, gb);
  190. if (gb.Where(a => a.key == 16 || a.key == 17).Count() == 2) return Utils.GetHandPokerComplieResult(HandPokerType.炸带二个, gb);
  191. }
  192. if (pokerLength == 5) { //顺子,三条带一对
  193. var gb1 = gb.Where(a => a.count == 1).Select(a => a.key).ToArray();
  194. if (gb1.Length == 5 && Utils.IsSeries(gb1)) return Utils.GetHandPokerComplieResult(HandPokerType.顺子, gb);
  195. if (gb.Where(a => a.count == 3).Any() && gb.Where(a => a.count == 2).Any()) return Utils.GetHandPokerComplieResult(HandPokerType.三条带一对, gb);
  196. }
  197. if (pokerLength == 6) { //顺子,连对,飞机,炸带二个
  198. var gb1 = gb.Where(a => a.count == 1).Select(a => a.key).ToArray();
  199. if (gb1.Length == 6 && Utils.IsSeries(gb1)) return Utils.GetHandPokerComplieResult(HandPokerType.顺子, gb);
  200. var gb2 = gb.Where(a => a.count == 2).Select(a => a.key).ToArray();
  201. if (gb2.Length == 3 && Utils.IsSeries(gb2)) return Utils.GetHandPokerComplieResult(HandPokerType.连对, gb);
  202. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  203. if (gb3.Length == 2 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机, gb);
  204. if (gb.Where(a => a.count == 4).Any()) return Utils.GetHandPokerComplieResult(HandPokerType.炸带二个, gb);
  205. if (gb.Where(a => a.key == 16 || a.key == 17).Count() == 2 && gb.Select(a => a.count == 2).Count() == 2) return Utils.GetHandPokerComplieResult(HandPokerType.炸带二个, gb);
  206. }
  207. if (pokerLength == 7) { //顺子
  208. var gb1 = gb.Where(a => a.count == 1).Select(a => a.key).ToArray();
  209. if (gb1.Length == 7 && Utils.IsSeries(gb1)) return Utils.GetHandPokerComplieResult(HandPokerType.顺子, gb);
  210. }
  211. if (pokerLength == 8) { //顺子,连对,飞机带个,炸带二对
  212. var gb1 = gb.Where(a => a.count == 1).Select(a => a.key).ToArray();
  213. if (gb1.Length == 8 && Utils.IsSeries(gb1)) return Utils.GetHandPokerComplieResult(HandPokerType.顺子, gb);
  214. var gb2 = gb.Where(a => a.count == 2).Select(a => a.key).ToArray();
  215. if (gb2.Length == 4 && Utils.IsSeries(gb2)) return Utils.GetHandPokerComplieResult(HandPokerType.连对, gb);
  216. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  217. if (gb3.Length == 2 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机带N个, gb);
  218. if (gb.Where(a => a.count == 4).Any() && gb.Where(a => a.count == 2).Count() == 2) return Utils.GetHandPokerComplieResult(HandPokerType.炸带二对, gb);
  219. }
  220. if (pokerLength == 9) { //顺子,飞机
  221. var gb1 = gb.Where(a => a.count == 1).Select(a => a.key).ToArray();
  222. if (gb1.Length == 9 && Utils.IsSeries(gb1)) return Utils.GetHandPokerComplieResult(HandPokerType.顺子, gb);
  223. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  224. if (gb3.Length == 3 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机, gb);
  225. }
  226. if (pokerLength == 10) { //顺子,连对,飞机带队
  227. var gb1 = gb.Where(a => a.count == 1).Select(a => a.key).ToArray();
  228. if (gb1.Length == 10 && Utils.IsSeries(gb1)) return Utils.GetHandPokerComplieResult(HandPokerType.顺子, gb);
  229. var gb2 = gb.Where(a => a.count == 2).Select(a => a.key).ToArray();
  230. if (gb2.Length == 5 && Utils.IsSeries(gb2)) return Utils.GetHandPokerComplieResult(HandPokerType.连对, gb);
  231. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  232. if (gb3.Length == 2 && Utils.IsSeries(gb3) && gb.Where(a => a.count == 2).Count() == 2) return Utils.GetHandPokerComplieResult(HandPokerType.飞机带N对, gb);
  233. }
  234. if (pokerLength == 11) { //顺子
  235. var gb1 = gb.Where(a => a.count == 1).Select(a => a.key).ToArray();
  236. if (gb1.Length == 11 && Utils.IsSeries(gb1)) return Utils.GetHandPokerComplieResult(HandPokerType.顺子, gb);
  237. }
  238. if (pokerLength == 12) { //顺子,连对,飞机,飞机带个
  239. var gb1 = gb.Where(a => a.count == 1).Select(a => a.key).ToArray();
  240. if (gb1.Length == 12 && Utils.IsSeries(gb1)) return Utils.GetHandPokerComplieResult(HandPokerType.顺子, gb);
  241. var gb2 = gb.Where(a => a.count == 2).Select(a => a.key).ToArray();
  242. if (gb2.Length == 6 && Utils.IsSeries(gb2)) return Utils.GetHandPokerComplieResult(HandPokerType.连对, gb);
  243. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  244. if (gb3.Length == 4 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机, gb);
  245. if (gb3.Length == 3 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机带N个, gb);
  246. }
  247. if (pokerLength == 14) { //连对
  248. var gb2 = gb.Where(a => a.count == 2).Select(a => a.key).ToArray();
  249. if (gb2.Length == 7 && Utils.IsSeries(gb2)) return Utils.GetHandPokerComplieResult(HandPokerType.连对, gb);
  250. }
  251. if (pokerLength == 15) { //飞机,飞机带队
  252. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  253. if (gb3.Length == 5 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机, gb);
  254. if (gb3.Length == 3 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机带N对, gb);
  255. }
  256. if (pokerLength == 16) { //连对,飞机带个
  257. var gb2 = gb.Where(a => a.count == 2).Select(a => a.key).ToArray();
  258. if (gb2.Length == 8 && Utils.IsSeries(gb2)) return Utils.GetHandPokerComplieResult(HandPokerType.连对, gb);
  259. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  260. if (gb3.Length == 4 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机带N个, gb);
  261. }
  262. if (pokerLength == 18) { //连对,飞机
  263. var gb2 = gb.Where(a => a.count == 2).Select(a => a.key).ToArray();
  264. if (gb2.Length == 9 && Utils.IsSeries(gb2)) return Utils.GetHandPokerComplieResult(HandPokerType.连对, gb);
  265. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  266. if (gb3.Length == 6 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机, gb);
  267. }
  268. if (pokerLength == 20) { //连对,飞机带个,飞机带队
  269. var gb2 = gb.Where(a => a.count == 2).Select(a => a.key).ToArray();
  270. if (gb2.Length == 10 && Utils.IsSeries(gb2)) return Utils.GetHandPokerComplieResult(HandPokerType.连对, gb);
  271. var gb3 = gb.Where(a => a.count == 3).Select(a => a.key).ToArray();
  272. if (gb3.Length == 5 && Utils.IsSeries(gb3)) return Utils.GetHandPokerComplieResult(HandPokerType.飞机带N个, gb);
  273. if (gb3.Length == 4 && Utils.IsSeries(gb3) && gb.Where(a => a.count == 2).Count() == 4) return Utils.GetHandPokerComplieResult(HandPokerType.飞机带N对, gb);
  274. }
  275. return null;
  276. }
  277. public static int CompareHandPoker(HandPokerInfo poker1, HandPokerInfo poker2) {
  278. if (poker1 == null) return -1;
  279. if (poker2 == null) return 1;
  280. switch (poker2.result.type) {
  281. case HandPokerType.:
  282. case HandPokerType.:
  283. case HandPokerType.三条:
  284. case HandPokerType.三条带一个:
  285. case HandPokerType.三条带一对:
  286. if (poker1.result.type == poker2.result.type) return poker1.result.compareValue.CompareTo(poker2.result.compareValue);
  287. if (poker1.result.type == HandPokerType.四条炸 || poker1.result.type == HandPokerType.王炸) return 1;
  288. return -1;
  289. case HandPokerType.顺子:
  290. case HandPokerType.连对:
  291. case HandPokerType.飞机:
  292. case HandPokerType.飞机带N个:
  293. case HandPokerType.飞机带N对:
  294. if (poker1.result.type == poker2.result.type && poker1.result.value.Length == poker1.result.value.Length) return poker1.result.compareValue.CompareTo(poker2.result.compareValue);
  295. if (poker1.result.type == HandPokerType.四条炸 || poker1.result.type == HandPokerType.王炸) return 1;
  296. return -1;
  297. case HandPokerType.炸带二个:
  298. case HandPokerType.炸带二对:
  299. if (poker1.result.type == poker2.result.type) return poker1.result.compareValue.CompareTo(poker2.result.compareValue);
  300. if (poker1.result.type == HandPokerType.四条炸 || poker1.result.type == HandPokerType.王炸) return 1;
  301. return -1;
  302. case HandPokerType.四条炸:
  303. case HandPokerType.王炸:
  304. if (poker1.result.type == poker2.result.type) return poker1.result.compareValue.CompareTo(poker2.result.compareValue);
  305. if (poker1.result.type == HandPokerType.四条炸 || poker1.result.type == HandPokerType.王炸) return 1;
  306. return -1;
  307. }
  308. return -1;
  309. }
  310. /// <summary>
  311. /// 从手中所有牌中,查找能压死 uphand 的打法
  312. /// </summary>
  313. /// <param name="allpoker">所有牌</param>
  314. /// <param name="uphand">要压死的牌</param>
  315. /// <returns></returns>
  316. public static List<int[]> GetAllTips(IEnumerable<int> allpoker, HandPokerInfo uphand) {
  317. var pokers = allpoker.ToArray();
  318. var gb = Utils.GroupByPoker(pokers);
  319. var jokers = gb.Where(a => a.count == 1 && a.key == 16 || a.key == 17).Select(a => a.poker.First()).ToArray();
  320. var ret = new List<int[]>();
  321. if (uphand == null) {
  322. var hand = Utils.ComplierHandPoker(gb); //尝试一手出完
  323. if (hand != null &&
  324. hand.type != HandPokerType.炸带二个 &&
  325. hand.type != HandPokerType.炸带二对)
  326. return new List<int[]>(new[] { hand.value });
  327. var gb1 = gb.Where(a => a.count == 1 && (jokers.Length == 2 && a.key != 16 && a.key != 17 || jokers.Length < 2)).OrderBy(a => a.key).FirstOrDefault(); //忽略双王
  328. var gb2 = gb.Where(a => a.count == 2).OrderBy(a => a.key).FirstOrDefault();
  329. if (gb1 != null && (gb2 == null || gb1.key < gb2.key)) return new List<int[]>(new[] { gb1.poker.ToArray() });
  330. if (gb2 != null && (gb1 == null || gb2.key < gb1.key)) return new List<int[]>(new[] { gb2.poker.ToArray() });
  331. return new List<int[]>(new[] { new[] { gb.Min(a => a.key) } });
  332. }
  333. if (uphand.result.type == HandPokerType.) {
  334. var gb1 = gb.Where(a => a.count == 1 && a.key > uphand.result.compareValue && (jokers.Length == 2 && a.key != 16 && a.key != 17 || jokers.Length < 2)).OrderBy(a => a.key); //忽略双王
  335. if (gb1.Any()) ret.AddRange(gb1.Select(a => a.poker.ToArray()));
  336. if (gb1.Any() == false) {
  337. var gb2 = gb.Where(a => a.count == 2 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  338. if (gb2.Any()) {
  339. foreach (var g2 in gb2) ret.AddRange(g2.poker.OrderBy(a => a).Select(a => new[] { a }));
  340. }
  341. }
  342. if (gb1.Any() == false) {
  343. var gb3 = gb.Where(a => a.count == 3 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  344. if (gb3.Any()) {
  345. foreach (var g3 in gb3) ret.AddRange(g3.poker.OrderBy(a => a).Select(a => new[] { a }));
  346. }
  347. }
  348. if (ret.Any() == false) {
  349. var gb4 = gb.Where(a => a.count == 4).OrderByDescending(a => a.key);
  350. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  351. }
  352. if (ret.Any() == false) {
  353. if (jokers.Length == 2) ret.Add(jokers);
  354. }
  355. return ret;
  356. }
  357. if (uphand.result.type == HandPokerType.) {
  358. var gb2 = gb.Where(a => a.count == 2 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  359. if (gb2.Any()) ret.AddRange(gb2.Select(a => a.poker.OrderByDescending(b => b).ToArray()));
  360. if (ret.Any() == false) {
  361. var gb3 = gb.Where(a => a.count == 3 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  362. if (gb3.Any()) ret.AddRange(gb3.Select(a => a.poker.Where((b, c) => c < 2).OrderByDescending(b => b).ToArray()));
  363. }
  364. if (ret.Any() == false) {
  365. var gb4 = gb.Where(a => a.count == 4).OrderByDescending(a => a.key);
  366. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(b => b).ToArray()));
  367. }
  368. if (ret.Any() == false) {
  369. if (jokers.Length == 2) ret.Add(jokers);
  370. }
  371. return ret;
  372. }
  373. if (uphand.result.type == HandPokerType.三条) {
  374. var gb3 = gb.Where(a => a.count == 3 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  375. if (gb3.Any()) ret.AddRange(gb3.Select(a => a.poker.OrderByDescending(b => b).ToArray()));
  376. var gb4 = gb.Where(a => a.count == 4).OrderBy(a => a.key);
  377. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  378. if (jokers.Length == 2) ret.Add(jokers);
  379. return ret;
  380. }
  381. if (uphand.result.type == HandPokerType.三条带一个) {
  382. var gb3 = gb.Where(a => a.count == 3 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  383. if (gb3.Any()) {
  384. foreach (var g3 in gb3) {
  385. var gb1 = gb.Where(a => a.count == 1 && (jokers.Length == 2 && a.key != 16 && a.key != 17 || jokers.Length < 2)).OrderBy(a => a.key); //忽略双王
  386. if (gb1.Any()) ret.AddRange(gb1.Select(a => g3.poker.OrderByDescending(b => b).Concat(a.poker).ToArray()));
  387. if (ret.Any() == false) {
  388. var gb2 = gb.Where(a => a.count == 2).OrderBy(a => a.key);
  389. if (gb2.Any()) {
  390. foreach (var g2 in gb2) ret.AddRange(g2.poker.OrderBy(a => a).Select(a => g3.poker.OrderByDescending(b => b).Concat(new[] { a }).ToArray()));
  391. }
  392. }
  393. if (ret.Any() == false) {
  394. var gb33 = gb.Where(a => a.count == 3 && a.key != g3.key).OrderBy(a => a.key);
  395. if (gb33.Any()) {
  396. foreach (var g33 in gb33) ret.AddRange(g33.poker.OrderBy(a => a).Select(a => g3.poker.OrderByDescending(b => b).Concat(new[] { a }).ToArray()));
  397. }
  398. }
  399. }
  400. }
  401. var gb4 = gb.Where(a => a.count == 4).OrderBy(a => a.key);
  402. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  403. if (jokers.Length == 2) ret.Add(jokers);
  404. return ret;
  405. }
  406. if (uphand.result.type == HandPokerType.三条带一对) {
  407. var gb3 = gb.Where(a => a.count == 3 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  408. if (gb3.Any()) {
  409. foreach (var g3 in gb3) {
  410. var gb2 = gb.Where(a => a.count == 2).OrderBy(a => a.key);
  411. if (gb2.Any()) ret.AddRange(gb2.Select(a => g3.poker.OrderByDescending(b => b).Concat(a.poker.OrderByDescending(b => b)).ToArray()));
  412. if (ret.Any() == false) {
  413. var gb33 = gb.Where(a => a.count == 3 && a.key != g3.key).OrderBy(a => a.key);
  414. if (gb33.Any()) ret.AddRange(gb33.Select(a => g3.poker.OrderByDescending(b => b).Concat(a.poker.Where((b, c) => c < 2).OrderByDescending(b => b)).ToArray()));
  415. }
  416. }
  417. }
  418. var gb4 = gb.Where(a => a.count == 4).OrderBy(a => a.key);
  419. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  420. if (jokers.Length == 2) ret.Add(jokers);
  421. return ret;
  422. }
  423. if (uphand.result.type == HandPokerType.顺子) {
  424. var gbs = gb.Where(a => a.count < 4 && a.key < 15 && a.key > uphand.result.compareValue - uphand.result.value.Length + 1).OrderBy(a => a.key).ToArray().AsSpan();
  425. if (gbs.IsEmpty == false) {
  426. for (var a = 0; a < gbs.Length && gbs.Length - a >= uphand.result.value.Length; a++) {
  427. var ses = gbs.Slice(a, uphand.result.value.Length).ToArray();
  428. if (Utils.IsSeries(ses.Select(b => b.key))) ret.Add(ses.Select(b => b.poker.First()).ToArray());
  429. }
  430. }
  431. var gb4 = gb.Where(a => a.count == 4).OrderBy(a => a.key);
  432. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  433. if (jokers.Length == 2) ret.Add(jokers);
  434. return ret;
  435. }
  436. if (uphand.result.type == HandPokerType.连对) {
  437. var gbs = gb.Where(a => a.count > 1 && a.count < 4 && a.key < 15 && a.key > uphand.result.compareValue - uphand.result.value.Length / 2 + 1).OrderBy(a => a.key).ToArray().AsSpan();
  438. if (gbs.IsEmpty == false) {
  439. for (var a = 0; a < gbs.Length && gbs.Length - a >= uphand.result.value.Length / 2; a++) {
  440. var ses = gbs.Slice(a, uphand.result.value.Length / 2).ToArray();
  441. if (Utils.IsSeries(ses.Select(b => b.key))) {
  442. var tmp2 = new List<int>();
  443. foreach (var se in ses) tmp2.AddRange(se.poker.Where((b, c) => c < 2).OrderByDescending(b => b));
  444. ret.Add(tmp2.ToArray());
  445. }
  446. }
  447. }
  448. var gb4 = gb.Where(a => a.count == 4).OrderBy(a => a.key);
  449. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  450. if (jokers.Length == 2) ret.Add(jokers);
  451. return ret;
  452. }
  453. if (uphand.result.type == HandPokerType.飞机) {
  454. var gbs = gb.Where(a => a.count >= 3 && a.key < 15 && a.key > uphand.result.compareValue - uphand.result.value.Length / 3 + 1).OrderBy(a => a.key).ToArray().AsSpan();
  455. if (gbs.IsEmpty == false) {
  456. for (var a = 0; a < gbs.Length && gbs.Length - a >= uphand.result.value.Length / 3; a++) {
  457. var ses = gbs.Slice(a, uphand.result.value.Length / 3).ToArray();
  458. if (Utils.IsSeries(ses.Select(b => b.key))) {
  459. var tmp3 = new List<int>();
  460. foreach (var se in ses) tmp3.AddRange(se.poker.Where((b, c) => c < 3).OrderByDescending(b => b));
  461. ret.Add(tmp3.ToArray());
  462. }
  463. }
  464. }
  465. var gb4 = gb.Where(a => a.count == 4).OrderBy(a => a.key);
  466. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  467. if (jokers.Length == 2) ret.Add(jokers);
  468. return ret;
  469. }
  470. if (uphand.result.type == HandPokerType.飞机带N个) {
  471. var gbs = gb.Where(a => a.count >= 3 && a.key < 15 && a.key > uphand.result.compareValue - uphand.result.value.Length / 4 + 1).OrderBy(a => a.key).ToArray().AsSpan();
  472. if (gbs.IsEmpty == false) {
  473. for (var a = 0; a < gbs.Length && gbs.Length - a >= uphand.result.value.Length / 4; a++) {
  474. var ses = gbs.Slice(a, uphand.result.value.Length / 4).ToArray();
  475. if (Utils.IsSeries(ses.Select(b => b.key))) {
  476. var tmp3 = new List<int>();
  477. foreach (var se in ses) tmp3.AddRange(se.poker.Where((b, c) => c < 3).OrderByDescending(b => b));
  478. var gb11 = gb.Where(z => z.count == 1 && (jokers.Length == 2 && z.key != 16 && z.key != 17 || jokers.Length < 2)).OrderBy(z => z.key); //忽略双王
  479. if (gb11.Any()) ret.AddRange(gb11.Select(z => tmp3.Concat(z.poker).ToArray()));
  480. if (ret.Any() == false) {
  481. var gb22 = gb.Where(z => z.count == 2).OrderBy(z => z.key);
  482. if (gb22.Any()) {
  483. foreach (var g22 in gb22) ret.AddRange(g22.poker.OrderBy(z => z).Select(z => tmp3.Concat(new[] { a }).ToArray()));
  484. }
  485. }
  486. if (ret.Any() == false) {
  487. var gb33 = gb.Where(z => z.count == 3 && ses.Where(y => y.key == z.key).Any() == false).OrderBy(z => z.key);
  488. if (gb33.Any()) {
  489. foreach (var g33 in gb33) ret.AddRange(g33.poker.OrderBy(z => a).Select(z => tmp3.Concat(new[] { a }).ToArray()));
  490. }
  491. }
  492. }
  493. }
  494. }
  495. var gb4 = gb.Where(a => a.count == 4).OrderBy(a => a.key);
  496. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  497. if (jokers.Length == 2) ret.Add(jokers);
  498. return ret;
  499. }
  500. if (uphand.result.type == HandPokerType.飞机带N对) {
  501. var gbs = gb.Where(a => a.count >= 3 && a.key < 15 && a.key > uphand.result.compareValue - uphand.result.value.Length / 5 + 1).OrderBy(a => a.key).ToArray().AsSpan();
  502. if (gbs.IsEmpty == false) {
  503. for (var a = 0; a < gbs.Length && gbs.Length - a >= uphand.result.value.Length / 5; a++) {
  504. var ses = gbs.Slice(a, uphand.result.value.Length / 5).ToArray();
  505. if (Utils.IsSeries(ses.Select(b => b.key))) {
  506. var tmp3 = new List<int>();
  507. foreach (var se in ses) tmp3.AddRange(se.poker.Where((b, c) => c < 3).OrderByDescending(b => b));
  508. var gb22 = gb.Where(z => z.count == 2).OrderBy(z => z.key);
  509. if (gb22.Any()) ret.AddRange(gb22.Select(z => tmp3.Concat(z.poker.OrderByDescending(b => b)).ToArray()));
  510. if (ret.Any() == false) {
  511. var gb33 = gb.Where(z => z.count == 3 && ses.Where(y => y.key == z.key).Any() == false).OrderBy(z => z.key);
  512. if (gb33.Any()) ret.AddRange(gb33.Select(z => tmp3.Concat(z.poker.Where((b, c) => c < 2).OrderByDescending(b => b)).ToArray()));
  513. }
  514. }
  515. }
  516. }
  517. var gb4 = gb.Where(a => a.count == 4).OrderBy(a => a.key);
  518. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  519. if (jokers.Length == 2) ret.Add(jokers);
  520. return ret;
  521. }
  522. if (uphand.result.type == HandPokerType.炸带二个) {
  523. var gb4 = gb.Where(a => a.count == 4 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  524. if (gb4.Any()) {
  525. foreach (var g4 in gb4) {
  526. var gb11 = gb.Where(z => z.count == 1 && (jokers.Length == 2 && z.key != 16 && z.key != 17 || jokers.Length < 2)).OrderBy(z => z.key).ToArray(); //忽略双王
  527. if (gb11.Length > 1) {
  528. for (var a = 0; a < gb11.Length; a++) {
  529. for (var b = a + 1; b < gb11.Length; b++) {
  530. ret.Add(g4.poker.OrderByDescending(z => z).Concat(gb11[a].poker).Concat(gb11[b].poker).ToArray());
  531. }
  532. }
  533. }
  534. if (ret.Any() == false) {
  535. var gb22 = gb.Where(z => z.count == 2).OrderBy(z => z.key);
  536. if (gb22.Any()) ret.AddRange(gb22.Select(y => g4.poker.OrderByDescending(z => z).Concat(y.poker.OrderByDescending(z => z)).ToArray()));
  537. }
  538. }
  539. ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  540. }
  541. if (jokers.Length == 2) {
  542. var gb11 = gb.Where(z => z.count == 1 && (jokers.Length == 2 && z.key != 16 && z.key != 17 || jokers.Length < 2)).OrderBy(z => z.key).ToArray(); //忽略双王
  543. if (gb11.Length > 1) {
  544. for (var a = 0; a < gb11.Length; a++) {
  545. for (var b = a + 1; b < gb11.Length; b++) {
  546. ret.Add(jokers.Concat(gb11[a].poker).Concat(gb11[b].poker).ToArray());
  547. }
  548. }
  549. }
  550. if (ret.Any() == false) {
  551. var gb22 = gb.Where(z => z.count == 2).OrderBy(z => z.key);
  552. if (gb22.Any()) ret.AddRange(gb22.Select(y => jokers.Concat(y.poker.OrderByDescending(z => z)).ToArray()));
  553. }
  554. ret.Add(jokers);
  555. }
  556. return ret;
  557. }
  558. if (uphand.result.type == HandPokerType.炸带二对) {
  559. var gb4 = gb.Where(a => a.count == 4 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  560. if (gb4.Any()) {
  561. foreach (var g4 in gb4) {
  562. var gb22 = gb.Where(z => z.count == 2).OrderBy(z => z.key).ToArray();
  563. if (gb22.Length > 1) {
  564. for (var a = 0; a < gb22.Length; a++) {
  565. for (var b = a + 1; b < gb22.Length; b++) {
  566. ret.Add(g4.poker.OrderByDescending(z => z).Concat(gb22[a].poker.OrderByDescending(z => z)).Concat(gb22[b].poker.OrderByDescending(z => z)).ToArray());
  567. }
  568. }
  569. }
  570. }
  571. ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  572. }
  573. if (jokers.Length == 2) {
  574. var gb22 = gb.Where(z => z.count == 2).OrderBy(z => z.key).ToArray();
  575. if (gb22.Length > 1) {
  576. for (var a = 0; a < gb22.Length; a++) {
  577. for (var b = a + 1; b < gb22.Length; b++) {
  578. ret.Add(jokers.Concat(gb22[a].poker.OrderByDescending(z => z)).Concat(gb22[b].poker.OrderByDescending(z => z)).ToArray());
  579. }
  580. }
  581. }
  582. ret.Add(jokers);
  583. }
  584. return ret;
  585. }
  586. if (uphand.result.type == HandPokerType.四条炸) {
  587. var gb4 = gb.Where(a => a.count == 4 && a.key > uphand.result.compareValue).OrderBy(a => a.key);
  588. if (gb4.Any()) ret.AddRange(gb4.Select(a => a.poker.OrderByDescending(z => z).ToArray()));
  589. if (jokers.Length == 2) ret.Add(jokers);
  590. return ret;
  591. }
  592. if (uphand.result.type == HandPokerType.王炸) {
  593. }
  594. return ret;
  595. }
  596. public class GroupByPokerResult {
  597. public int key { get; set; }
  598. public int count { get; set; }
  599. public IEnumerable<int> poker { get; set; }
  600. }
  601. class GroupByPokerTmpResult {
  602. internal int count { get; set; } = 0;
  603. internal List<int> poker { get; set; } = new List<int>();
  604. }
  605. }
  606. }