/// <summary>
 /// Given a set of pocket cards and a set of board cards this function returns the odds of winning or tying for a player and a random opponent.
 /// </summary>
 /// <param name="pocketcards">Pocket cards in ASCII</param>
 /// <param name="boardcards">Board cards in ASCII</param>
 /// <param name="player">Player odds as doubles</param>
 /// <param name="opponent">Opponent odds as doubles</param>
 public static void HandPlayerOpponentOdds(string pocketcards, string boardcards, ref double[] player, ref double[] opponent)
 {
     HandPlayerOpponentOdds(Hand.ParseHand(pocketcards), Hand.ParseHand(boardcards), ref player, ref opponent);
 }
        /// <summary>
        /// Used to calculate the wining information about each players hand. This function enumerates all
        /// possible remaining hands and tallies win, tie and losses for each player. This function typically takes
        /// well less than a second regardless of the number of players.
        /// </summary>
        /// <param name="pockets">Array of pocket hand string, one for each player</param>
        /// <param name="board">the board cards</param>
        /// <param name="dead">the dead cards</param>
        /// <param name="wins">An array of win tallies, one for each player</param>
        /// <param name="ties">An array of tie tallies, one for each player</param>
        /// <param name="losses">An array of losses tallies, one for each player</param>
        /// <param name="totalHands">The total number of hands enumarated.</param>
        public static void HandOdds(string[] pockets, string board, string dead, long[] wins, long[] ties, long[] losses, ref long totalHands)
        {
            ulong[] pocketmasks = new ulong[pockets.Length];
            ulong[] pockethands = new ulong[pockets.Length];
            int     count = 0, bestcount;
            ulong   boardmask = 0UL, deadcards_mask = 0UL, deadcards = Hand.ParseHand(dead, ref count);

            totalHands      = 0;
            deadcards_mask |= deadcards;

            // Read pocket cards
            for (int i = 0; i < pockets.Length; i++)
            {
                count          = 0;
                pocketmasks[i] = Hand.ParseHand(pockets[i], "", ref count);
                if (count != 2)
                {
                    throw new ArgumentException("There must be two pocket cards.");                     // Must have 2 cards in each pocket card set.
                }
                deadcards_mask |= pocketmasks[i];
                wins[i]         = ties[i] = losses[i] = 0;
            }

            // Read board cards
            count     = 0;
            boardmask = Hand.ParseHand("", board, ref count);


#if DEBUG
            Debug.Assert(count >= 0 && count <= 5);             // The board must have zero or more cards but no more than a total of 5

            // Check pocket cards, board, and dead cards for duplicates
            if ((boardmask & deadcards) != 0)
            {
                throw new ArgumentException("Duplicate between cards dead cards and board");
            }

            // Validate the input
            for (int i = 0; i < pockets.Length; i++)
            {
                for (int j = i + 1; j < pockets.Length; j++)
                {
                    if ((pocketmasks[i] & pocketmasks[j]) != 0)
                    {
                        throw new ArgumentException("Duplicate pocket cards");
                    }
                }

                if ((pocketmasks[i] & boardmask) != 0)
                {
                    throw new ArgumentException("Duplicate between cards pocket and board");
                }

                if ((pocketmasks[i] & deadcards) != 0)
                {
                    throw new ArgumentException("Duplicate between cards pocket and dead cards");
                }
            }
#endif

            // Iterate through all board possiblities that doesn't include any pocket cards.
            foreach (ulong boardhand in Hands(boardmask, deadcards_mask, 5))
            {
                // Evaluate all hands and determine the best hand
                ulong bestpocket = Evaluate(pocketmasks[0] | boardhand, 7);
                pockethands[0] = bestpocket;
                bestcount      = 1;
                for (int i = 1; i < pockets.Length; i++)
                {
                    pockethands[i] = Evaluate(pocketmasks[i] | boardhand, 7);
                    if (pockethands[i] > bestpocket)
                    {
                        bestpocket = pockethands[i];
                        bestcount  = 1;
                    }
                    else if (pockethands[i] == bestpocket)
                    {
                        bestcount++;
                    }
                }

                // Calculate wins/ties/loses for each pocket + board combination.
                for (int i = 0; i < pockets.Length; i++)
                {
                    if (pockethands[i] == bestpocket)
                    {
                        if (bestcount > 1)
                        {
                            ties[i]++;
                        }
                        else
                        {
                            wins[i]++;
                        }
                    }
                    else if (pockethands[i] < bestpocket)
                    {
                        losses[i]++;
                    }
                }

                totalHands++;
            }
        }