示例#1
0
文件: Hand.cs 项目: wattcode/SnapCall
        public HandStrength GetStrength()
        {
            if (Cards.Count == 5)
            {
                var strength = new HandStrength();
                strength.Kickers = new List <int>();

                Cards = Cards.OrderBy(card => card.PrimeRank * 100 + card.PrimeSuit).ToList();

                int rankProduct = Cards.Select(card => card.PrimeRank).Aggregate((acc, r) => acc * r);
                int suitProduct = Cards.Select(card => card.PrimeSuit).Aggregate((acc, r) => acc * r);

                bool straight =
                    rankProduct == 8610 ||                          // 5-high straight
                    rankProduct == 2310 ||                          // 6-high straight
                    rankProduct == 15015 ||                         // 7-high straight
                    rankProduct == 85085 ||                         // 8-high straight
                    rankProduct == 323323 ||                        // 9-high straight
                    rankProduct == 1062347 ||                       // T-high straight
                    rankProduct == 2800733 ||                       // J-high straight
                    rankProduct == 6678671 ||                       // Q-high straight
                    rankProduct == 14535931 ||                      // K-high straight
                    rankProduct == 31367009;                        // A-high straight

                bool flush =
                    suitProduct == 147008443 ||                         // Spades
                    suitProduct == 229345007 ||                         // Hearts
                    suitProduct == 418195493 ||                         // Diamonds
                    suitProduct == 714924299;                           // Clubs

                var cardCounts = Cards.GroupBy(card => (int)card.Rank).Select(group => group).ToList();

                var fourOfAKind  = -1;
                var threeOfAKind = -1;
                var onePair      = -1;
                var twoPair      = -1;

                foreach (var group in cardCounts)
                {
                    var rank  = group.Key;
                    var count = group.Count();
                    if (count == 4)
                    {
                        fourOfAKind = rank;
                    }
                    else if (count == 3)
                    {
                        threeOfAKind = rank;
                    }
                    else if (count == 2)
                    {
                        twoPair = onePair;
                        onePair = rank;
                    }
                }

                if (straight && flush)
                {
                    strength.HandRanking = HandRanking.StraightFlush;
                    strength.Kickers     = Cards.Select(card => (int)card.Rank).Reverse().ToList();
                }
                else if (fourOfAKind >= 0)
                {
                    strength.HandRanking = HandRanking.FourOfAKind;
                    strength.Kickers.Add(fourOfAKind);
                    strength.Kickers.AddRange(Cards
                                              .Where(card => (int)card.Rank != fourOfAKind)
                                              .Select(card => (int)card.Rank));
                }
                else if (threeOfAKind >= 0 && onePair >= 0)
                {
                    strength.HandRanking = HandRanking.FullHouse;
                    strength.Kickers.Add(threeOfAKind);
                    strength.Kickers.Add(onePair);
                }
                else if (flush)
                {
                    strength.HandRanking = HandRanking.Flush;
                    strength.Kickers.AddRange(Cards
                                              .Select(card => (int)card.Rank)
                                              .Reverse());
                }
                else if (straight)
                {
                    strength.HandRanking = HandRanking.Straight;
                    strength.Kickers.AddRange(Cards
                                              .Select(card => (int)card.Rank)
                                              .Reverse());
                }
                else if (threeOfAKind >= 0)
                {
                    strength.HandRanking = HandRanking.ThreeOfAKind;
                    strength.Kickers.Add(threeOfAKind);
                    strength.Kickers.AddRange(Cards
                                              .Where(card => (int)card.Rank != threeOfAKind)
                                              .Select(card => (int)card.Rank));
                }
                else if (twoPair >= 0)
                {
                    strength.HandRanking = HandRanking.TwoPair;
                    strength.Kickers.Add(Math.Max(twoPair, onePair));
                    strength.Kickers.Add(Math.Min(twoPair, onePair));
                    strength.Kickers.AddRange(Cards
                                              .Where(card => (int)card.Rank != twoPair && (int)card.Rank != onePair)
                                              .Select(card => (int)card.Rank));
                }
                else if (onePair >= 0)
                {
                    strength.HandRanking = HandRanking.Pair;
                    strength.Kickers.Add(onePair);
                    strength.Kickers.AddRange(Cards
                                              .Where(card => (int)card.Rank != onePair)
                                              .Select(card => (int)card.Rank));
                }
                else
                {
                    strength.HandRanking = HandRanking.HighCard;
                    strength.Kickers.AddRange(Cards
                                              .Select(card => (int)card.Rank)
                                              .Reverse());
                }

                return(strength);
            }

            else
            {
                return(null);
            }
        }
示例#2
0
        private void GenerateFiveCardTable()
        {
            var sourceSet    = Enumerable.Range(0, 52).ToList();
            var combinations = new Combinatorics.Collections.Combinations <int>(sourceSet, 5);

            // Generate all possible 5 card hand bitmaps
            Console.WriteLine("Generating bitmaps");
            var handBitmaps = new List <ulong>();
            int count       = 0;

            foreach (List <int> values in combinations)
            {
                if (debug && count++ % 1000 == 0)
                {
                    Console.Write("{0} / {1}\r", count, combinations.Count);
                }
                handBitmaps.Add(values.Aggregate(0ul, (acc, el) => acc | (1ul << el)));
            }

            // Calculate hand strength of each hand
            Console.WriteLine("Calculating hand strength");
            var handStrengths = new Dictionary <ulong, HandStrength>();

            count = 0;
            foreach (ulong bitmap in handBitmaps)
            {
                if (debug && count++ % 1000 == 0)
                {
                    Console.Write("{0} / {1}\r", count, handBitmaps.Count);
                }
                var hand = new Hand(bitmap);
                handStrengths.Add(bitmap, hand.GetStrength());
            }

            // Generate a list of all unique hand strengths
            Console.WriteLine("Generating equivalence classes");
            var uniqueHandStrengths = new List <HandStrength>();

            count = 0;
            foreach (KeyValuePair <ulong, HandStrength> strength in handStrengths)
            {
                if (debug && count++ % 1000 == 0)
                {
                    Console.Write("{0} / {1}\r", count, handStrengths.Count);
                }
                Utilities.BinaryInsert <HandStrength>(uniqueHandStrengths, strength.Value);
            }
            Console.WriteLine("{0} unique hand strengths", uniqueHandStrengths.Count);

            // Create a map of hand bitmaps to hand strength indices
            Console.WriteLine("Creating lookup table");
            count = 0;
            foreach (ulong bitmap in handBitmaps)
            {
                if (debug && count++ % 1000 == 0)
                {
                    Console.Write("{0} / {1}\r", count, handBitmaps.Count);
                }
                var          hand        = new Hand(bitmap);
                HandStrength strength    = hand.GetStrength();
                var          equivalence = Utilities.BinarySearch <HandStrength>(uniqueHandStrengths, strength);
                if (equivalence == null)
                {
                    throw new Exception(string.Format("{0} hand not found", hand));
                }
                else
                {
                    handRankMap[bitmap] = (ulong)equivalence;
                }
            }
        }
示例#3
0
        private void GenerateFiveCardTable()
        {
            var sourceSet    = Enumerable.Range(0, 52).ToList();
            var combinations = new Combinatorics.Collections.Combinations <int>(sourceSet, 5);

            // Generate all possible 5 card hand bitmaps
            var handBitmaps = new List <ulong>();

            using (var progress = new ProgressBar())
            {
                long sharedLoopCounter = 0;

                foreach (List <int> values in combinations)
                {
                    handBitmaps.Add(values.Aggregate(0ul, (acc, el) => acc | (1ul << el)));
                    sharedLoopCounter++;
                    progress.Report((double)sharedLoopCounter / combinations.Count, sharedLoopCounter);
                }
            }

            // Calculate hand strength of each hand
            var handStrengths = new Dictionary <ulong, HandStrength>();

            Console.WriteLine("Calculating hand strength (" + handBitmaps.Count + ")");

            using (var progress = new ProgressBar())
            {
                long sharedLoopCounter = 0;

                foreach (ulong bitmap in handBitmaps)
                {
                    var hand = new Hand(bitmap);
                    handStrengths.Add(bitmap, hand.GetStrength());
                    sharedLoopCounter++;
                    progress.Report((double)sharedLoopCounter / handBitmaps.Count, sharedLoopCounter);
                }
            }

            // Generate a list of all unique hand strengths
            var uniqueHandStrengths = new List <HandStrength>();

            Console.WriteLine("Generating equivalence classes");

            using (var progress = new ProgressBar())
            {
                long sharedLoopCounter = 0;

                foreach (KeyValuePair <ulong, HandStrength> strength in handStrengths)
                {
                    Utilities.BinaryInsert(uniqueHandStrengths, strength.Value);
                    sharedLoopCounter++;
                    progress.Report((double)sharedLoopCounter / handStrengths.Count, sharedLoopCounter);
                }
            }
            Console.WriteLine("{0} unique hand strengths", uniqueHandStrengths.Count);

            // Create a map of hand bitmaps to hand strength indices
            Console.WriteLine("Generating new five card lookup table (2'598'960)");
            using (var progress = new ProgressBar())
            {
                long sharedLoopCounter = 0;

                foreach (ulong bitmap in handBitmaps)
                {
                    var          hand        = new Hand(bitmap);
                    HandStrength strength    = hand.GetStrength();
                    var          equivalence = Utilities.BinarySearch(uniqueHandStrengths, strength);
                    if (equivalence == null)
                    {
                        throw new Exception(string.Format("{0} hand not found", hand));
                    }
                    else
                    {
                        handRankMap[bitmap] = (ulong)equivalence;
                    }
                    sharedLoopCounter++;
                    progress.Report((double)sharedLoopCounter / handBitmaps.Count, sharedLoopCounter);
                }
            }
        }