/// <summary>Calculates the winning change of a hand.</summary>
        public static PokerHandOutcome Calculate(Cards hand, Cards table, MT19937Generator rnd, int runs = 1000)
        {
            UInt64Cards[] tblSub = null;

            var tAdd = 5 - table.Count;
            var uhnd = UInt64Cards.Create(hand);
            var utbl = UInt64Cards.Create(table);
            var dead = uhnd.Combine(utbl);

            var ownSub = uhnd.GetHandSubsets();

            var w = 0;
            var d = 0;
            var l = 0;

            if (tAdd == 0)
            {
                tblSub = utbl.GetTableSubsets();
            }

            for (var i = 0; i < runs; i++)
            {
                var tbl = utbl;
                if (tAdd > 0)
                {
                    tbl    = tbl.Combine(UInt64Cards.GetRandom(dead, tAdd, rnd));
                    tblSub = tbl.GetTableSubsets();
                }
                var uopp   = UInt64Cards.GetRandom(dead.Combine(tbl), 4, rnd);
                var oppSub = uopp.GetHandSubsets();

                var c = UInt32PokerHand.Compare(ownSub, oppSub, tblSub);
                if (c > 0)
                {
                    w++;
                }
                else if (c < 0)
                {
                    l++;
                }
                else
                {
                    d++;
                }
            }
            return(new PokerHandOutcome(w, d, l));
        }
Ejemplo n.º 2
0
        /// <summary>Gets the score of a the cards.</summary>
        public UInt32PokerHand GetScore()
        {
#if DEBUG
            if (this.Count != 5)
            {
                throw new InvalidOperationException("The number of cards is not 5.");
            }
#endif
            uint rankX, mask1, mask2, mask3, mask4;

            var sd = CardMask(mask, CardSuit.Diamonds);
            var sc = CardMask(mask, CardSuit.Clubs);
            var sh = CardMask(mask, CardSuit.Hearts);
            var ss = CardMask(mask, CardSuit.Spades);

            var mask5      = sc | sd | sh | ss;
            var mask5Count = Bits.Count(mask5);

            switch (mask5Count)
            {
            // FourOfAKind or FullHouse
            case 2:
                mask4 = sh & sd & sc & ss;
                if (mask4 != 0)
                {
                    rankX = GetSingleValue(mask4) | (mask5 ^ mask4);
                    return(UInt32PokerHand.Create(PokerHandType.FourOfAKind, rankX));
                }
                else
                {
                    mask3 = ((sc & sd) | (sh & ss)) & ((sc & sh) | (sd & ss));
                    rankX = GetSingleValue(mask3) | (mask5 ^ mask3);
                    return(UInt32PokerHand.Create(PokerHandType.FullHouse, rankX));
                }

            // Three of a kind, or two pair.
            case 3:
                mask2 = mask5 ^ (sc ^ sd ^ sh ^ ss);
                if (mask2 != 0)
                {
                    rankX  = mask2 << 4;
                    mask1  = mask5 ^ mask2;
                    rankX |= GetSingleValue(mask1) >> 13;
                    return(UInt32PokerHand.Create(PokerHandType.TwoPair, rankX));
                }
                else
                {
                    mask3 = ((sc & sd) | (sh & ss)) & ((sc & sh) | (sd & ss));
                    rankX = GetSingleValue(mask3) | (mask5 ^ mask3);
                    return(UInt32PokerHand.Create(PokerHandType.ThreeOfAKind, rankX));
                }

            // One pair.
            case 4:
                mask2 = mask5 ^ (sc ^ sd ^ sh ^ ss);
                rankX = GetSingleValue(mask2) | (mask5 ^ mask2);
                return(UInt32PokerHand.Create(PokerHandType.OnePair, rankX));

            // Straight and or flush, or high card.
            case 5:
            default:
                rankX = GetStraightValue(mask5);
                if (rankX != 0)
                {
                    return(UInt32PokerHand.Create(IsFlush ? PokerHandType.StraightFlush : PokerHandType.Straight, rankX));
                }
                if (IsFlush)
                {
                    return(UInt32PokerHand.Create(PokerHandType.Flush, mask5));
                }
                return(UInt32PokerHand.Create(PokerHandType.HighCard, mask5));
            }
        }