public static CombinationType GetFinalCombinations(CardSet[] sets, out Dictionary <int, Card[]> resultCards) { Card[] common = sets[0]._cards.Intersect(sets[1]._cards).ToArray(); CardSet max = sets[0]; for (int i = 1; i < sets.Length; i++) { if (CardSet.Compare(max, sets[i]) < 0) { max = sets[i]; } } int[] maxes = sets.Where(s => CardSet.Compare(s, max) == 0).Select(s => Array.IndexOf(sets, s)).ToArray(); resultCards = new Dictionary <int, Card[]>(); foreach (int i in maxes) { if (sets[i]._cards.Length != CARDS_COUNT) { throw new Exception(); } switch (sets[i].Type) { default: resultCards.Add(i, sets[i]._cards.OrderByDescending(c => c.Number).Take(5).ToArray()); break; case CombinationType.PAIR: var pair = sets[i]._cards.GroupBy(c => c.Number).OrderByDescending(c => c.Key).First(g => g.Count() == 2); resultCards.Add(i, sets[i]._cards.Where(c => c.Number == pair.Key).Union(sets[i]._cards.Where(c => c.Number != pair.Key).OrderByDescending(c => c.Number).Take(3)).ToArray()); break; case CombinationType.PAIR2: var pairs = sets[i]._cards.GroupBy(c => c.Number).Where(g => g.Count() == 2).OrderByDescending(c => c.Key).Take(2).ToArray(); resultCards.Add(i, sets[i]._cards.Where(c => c.Number == pairs[0].Key).Union(sets[i]._cards.Where(c => c.Number == pairs[1].Key)).Union(sets[i]._cards.Where(c => c.Number != pairs[0].Key && c.Number != pairs[1].Key).OrderByDescending(c => c.Number).Take(1)).ToArray()); break; case CombinationType.THREE: var three = sets[i]._cards.GroupBy(c => c.Number).OrderByDescending(c => c.Key).First(g => g.Count() == 3); resultCards.Add(i, sets[i]._cards.Where(c => c.Number == three.Key).Union(sets[i]._cards.Where(c => c.Number != three.Key).OrderByDescending(c => c.Number).Take(2)).ToArray()); break; case CombinationType.STRAIGHT: // с учетом того, что какое-то из достоинств может быть и на столе, и на руках bool isFound = false; var numbers = sets[i]._cards.GroupBy(c => c.Number).OrderByDescending(g => g.Key).ToArray(); for (int j = 0; j < numbers.Length - 4; j++) { var sequence = numbers.Skip(j).Take(5).ToArray(); if ((int)sequence[0].Key - 4 == (int)sequence[4].Key) { resultCards.Add(i, sequence.Select(g => g.OrderByDescending(c => common.Contains(c) ? 1 : 0).First()).ToArray()); isFound = true; break; } } if (!isFound) { if (numbers[0].Key == NumberType.A && numbers[numbers.Length - 4].Key == NumberType._5) { resultCards.Add(i, new Card[] { numbers[0].First(), numbers[numbers.Length - 4].First(), numbers[numbers.Length - 3].First(), numbers[numbers.Length - 2].First(), numbers[numbers.Length - 1].First() }); } } break; case CombinationType.FLUSH: resultCards.Add(i, sets[i]._cards.GroupBy(c => c.Flush).First(g => g.Count() >= 5).OrderByDescending(c => c.Number).Take(5).ToArray()); break; case CombinationType.FULL_HOUSE: // с учетом того, что какое-то из достоинств может быть и на столе, и на руках var fhThree = sets[i]._cards.GroupBy(c => c.Number).OrderByDescending(c => c.Key).First(g => g.Count() == 3); var fhPair = sets[i]._cards.Where(c => c.Number != fhThree.Key).GroupBy(c => c.Number).OrderByDescending(c => c.Key).First(g => g.Count() >= 2 && g.Count() <= 3); resultCards.Add(i, sets[i]._cards.Where(c => c.Number == fhThree.Key).Union(sets[i]._cards.Where(c => c.Number == fhPair.Key).OrderByDescending(c => common.Contains(c) ? 1 : 0).Take(2)).ToArray()); break; case CombinationType.FOUR: var four = sets[i]._cards.GroupBy(c => c.Number).OrderByDescending(c => c.Key).First(g => g.Count() == 4); resultCards.Add(i, sets[i]._cards.Where(c => c.Number == four.Key).Union(sets[i]._cards.Where(c => c.Number != four.Key).OrderByDescending(c => c.Number).Take(1)).ToArray()); break; case CombinationType.STRAIGHT_FLUSH: bool isFoundSF = false; var sfNumbers = sets[i]._cards.GroupBy(c => c.Flush).First(g => g.Count() >= 5).OrderByDescending(c => c.Number).ToArray(); // все карты нужной масти, отсортированные по убыванию for (int j = 0; j < sfNumbers.Count() - 4; j++) { var sequence = sfNumbers.Skip(j).Take(5).ToArray(); if ((int)sequence[0].Number == (int)sequence[4].Number + 4) // если есть 5 идущих по порядку карт { resultCards.Add(i, sequence); isFoundSF = true; break; } } if (!isFoundSF) // если нет 5 идущих по порядку карт { if (sfNumbers[0].Number == NumberType.A && sfNumbers[sfNumbers.Length - 4].Number == NumberType._5) // если стрит-флэш на 5, 4, 3, 2, A { resultCards.Add(i, new Card[] { sfNumbers[0], sfNumbers[sfNumbers.Length - 4], sfNumbers[sfNumbers.Length - 3], sfNumbers[sfNumbers.Length - 2], sfNumbers[sfNumbers.Length - 1] }); } } break; case CombinationType.ROYAL_FLUSH: resultCards.Add(i, sets[i]._cards.GroupBy(c => c.Flush).First(g => g.Count() >= 5).OrderByDescending(c => c.Number).Take(5).ToArray()); break; } } return(sets[maxes[0]].Type); }
private void GetCountsInternal(int rawIndex, int netIndex, int flushMask)//, int cutLevel) { CardSet[] sets = new CardSet[_players.Length]; int maxFlush = -1, maxFlushCount = 0; if (flushMask > 0) { int curFlushCount = 0; for (int j = 0; j < 4; j++) { curFlushCount = (flushMask % CardSet.Powers6[j]) / CardSet.Powers6[j + 1]; if (curFlushCount >= 3) { maxFlushCount = curFlushCount; maxFlush = j; } } } bool isFlush; int n, kCounter = 0; NumberType[] numbers; for (int i = 0; i < _players.Length; i++) { isFlush = false; numbers = null; if (flushMask > 0 && maxFlush >= 0) { if (isFlush = _flushesCounts[maxFlush, i] + maxFlushCount >= 5) { kCounter = 0; numbers = new NumberType[_flushesCounts[maxFlush, i] + maxFlushCount]; for (int k = 0; k < _players[i].Length; k++) { if (_players[i][k].Flush == (FlushType)maxFlush) { numbers[kCounter++] = _players[i][k].Number; } } for (int k = 0; k < COMMON_CARDS_COUNT; k++) { n = ((rawIndex % CardSet.Powers52[k]) / CardSet.Powers52[k + 1]); if ((n & 3) == maxFlush) { numbers[kCounter++] = (NumberType)(n >> 2); } } Array.Sort(numbers); Array.Reverse(numbers); } } sets[i] = new CardSet(_playerIndices[i] + netIndex, _players[i], isFlush, numbers); } List <Tuple <int, CardSet> > maxes = new List <Tuple <int, CardSet> >(); maxes.Add(Tuple.Create(0, sets[0])); int result = 0; for (int i = 1; i < sets.Length; i++) { result = CardSet.Compare(maxes[0].Item2, sets[i]); if (result < 0) { maxes.Clear(); maxes.Add(Tuple.Create(i, sets[i])); } else if (result == 0) { maxes.Add(Tuple.Create(i, sets[i])); } } lock (Counts) { double inc = increment[maxes.Count]; foreach (var max in maxes) { Counts[max.Item1][(int)max.Item2.Type] += inc; } Counts[_players.Length][(int)maxes[0].Item2.Type] += inc; } }
public static int Compare(CardSet c1, CardSet c2) { int value = c1.Type.CompareTo(c2.Type); if (value != 0) { return(value); } else { if (c1.Type == CombinationType.FLUSH) { for (int i = 0; i < 5; i++) { value = c1._kicker[i].CompareTo(c2._kicker[i]); if (value != 0) { break; } } return(value); } else { value = c1._kicker[0].CompareTo(c2._kicker[0]); if (value != 0) { return(value); } else if (c1.Type != CombinationType.STRAIGHT && c1.Type != CombinationType.STRAIGHT_FLUSH && c1.Type != CombinationType.ROYAL_FLUSH) { value = c1._kicker[1].CompareTo(c2._kicker[1]); if (value != 0) { return(value); } else if (c1.Type != CombinationType.FOUR && c1.Type != CombinationType.FULL_HOUSE) { value = c1._kicker[2].CompareTo(c2._kicker[2]); if (value != 0) { return(value); } else if (c1.Type != CombinationType.THREE && c1.Type != CombinationType.PAIR2) { Func <int, NumberType[]> getCards = x => Enumerable.Range(0, 5).Select(i => (NumberType)((x % Powers13[i]) / Powers13[i + 1])).ToArray(); NumberType[] nc1 = c1._cards.Select(c => c.Number).Union(getCards(c1._index)).Where(c => !c1._kicker.Contains(c)).ToArray(); NumberType[] nc2 = c2._cards.Select(c => c.Number).Union(getCards(c2._index)).Where(c => !c2._kicker.Contains(c)).ToArray(); Array.Sort(nc1); Array.Sort(nc2); value = nc1[nc1.Length - 1].CompareTo(nc2[nc2.Length - 1]); if (value == 0 && c1.Type == CombinationType.NONE) { value = nc1[nc1.Length - 2].CompareTo(nc2[nc2.Length - 2]); } return(value); } } } } } return(value); }