/// <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));
        }
        /// <summary>Returns a random hand with the specified number of cards and constrained
        /// to not contain any of the passed dead cards.
        /// </summary>
        /// <param name="dead">Mask for the cards that must not be returned.</param>
        /// <param name="ncards">The number of cards to return in this hand.</param>
        /// <param name="rnd">An instance of the Random class.</param>
        /// <returns>A randomly chosen hand containing the number of cards requested.</returns>
        public static UInt64Cards GetRandom(UInt64Cards dead, int ncards, MT19937Generator rnd)
        {
            // Return a random hand.
            ulong mask = 0UL, card;

            for (int i = 0; i < ncards; i++)
            {
                do
                {
                    card = Bits.Flag[rnd.Next(52)];
                }while (((dead.mask | mask) & card) != 0);

                mask |= card;
            }

            return(new UInt64Cards(mask));
        }
        /// <summary>Creates sub hands.</summary>
        public static UInt64Cards[] CreateSubHands(Cards hand)
        {
            var supHands = new UInt64Cards[6];

            for (int i = 0; i < 6; i++)
            {
                var subset = new List <Card>();
                for (var p = 0; p < 4; p++)
                {
                    if ((Bits.Flag[p] & Mask4Over2[i]) != 0)
                    {
                        subset.Add(hand[p]);
                    }
                }
                supHands[i] = UInt64Cards.Create(subset);
            }
            return(supHands);
        }
        /// <summary>Gets a sub set of tables of the deck.</summary>
        public UInt64Cards[] GetTableSubsets()
        {
            var subsets = new UInt64Cards[10];
            var indexes = GetMaskIndexes(5);

            for (var i = 0; i < 10; i++)
            {
                ulong s = 0;
                for (var p = 0; p < 6; p++)
                {
                    if ((Bits.Flag[p] & Mask5Over3[i]) != 0)
                    {
                        s |= indexes[p];
                    }
                }
                subsets[i] = new UInt64Cards(s);
            }
            return(subsets);
        }
        /// <summary>Gets a sub set of hands of the deck.</summary>
        public UInt64Cards[] GetHandSubsets()
        {
            var subsets = new UInt64Cards[6];
            var indexes = GetMaskIndexes(4);

            for (var i = 0; i < 6; i++)
            {
                ulong s = 0;
                for (var p = 0; p < 5; p++)
                {
                    if ((Bits.Flag[p] & Mask4Over2[i]) != 0)
                    {
                        s |= indexes[p];
                    }
                }
                subsets[i] = new UInt64Cards(s);
            }
            return(subsets);
        }
 /// <summary>Remove selection from hand.</summary>
 public UInt64Cards Combine(UInt64Cards s0, UInt64Cards s1)
 {
     return(new UInt64Cards(mask | s0.mask | s1.mask));
 }
 /// <summary>Remove selection from hand.</summary>
 public UInt64Cards Combine(UInt64Cards selection)
 {
     return(new UInt64Cards(mask | selection.mask));
 }
 /// <summary>Remove selection from hand.</summary>
 public UInt64Cards Remove(UInt64Cards selection)
 {
     return(new UInt64Cards(mask ^ selection.mask));
 }