Beispiel #1
0
        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);
        }
Beispiel #2
0
        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;
            }
        }
Beispiel #3
0
        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);
        }