private void ReportEVEquity(StringBuilder result, EVRange equity, Hand hand, IRange manyHands)
        {
            // EVRange class, which is a holder for EV and Equity results contains for each hand values of
            // calculated EV, total number of matchups and total winnings.
            // Except for some corner cases EV is equal Wins/ Matchups
            double handEV = equity[hand].EV;

            // Calculation of total EV for a given range we have to a be careful.
            // We cannot simply average p out the EV's, because different hands have different weights.
            // It is also not enough to simply weight them with the current range as this does not
            // take into account the card removal effect. The proper way is to calculated weighted EV
            // weighted by the number of different matchups the given hand will play.
            // To do this we will sum the total winnings of all hands in the range and divide it by the total
            // number of matchups played.
            double rangeWins     = 0;
            double rangeMatchups = 0;

            foreach (var singleCombo in manyHands)
            {
                EVHolder ev = equity[singleCombo];
                // This is important consideration. Impossible hands are reported by the solver as 0 matchups and NaN Wins.
                // We don't want to add NaNs to the running sum so we need this check
                if (ev.Matchups > 0)
                {
                    rangeWins     += ev.Wins;
                    rangeMatchups += ev.Matchups;
                }
            }

            //To calculate the total EV for all range we repeat the same process
            double totalWins     = 0;
            double totalMatchups = 0;

            foreach (var singleCombo in equity)
            {
                EVHolder ev = equity[singleCombo];
                if (ev.Matchups > 0)
                {
                    totalWins     += ev.Wins;
                    totalMatchups += ev.Matchups;
                }
            }

            result.AppendLine("for single hand  " + hand.ToUnicodeString() + " = " + handEV);
            result.AppendLine("for hands " + manyHands.ToSingleLineString() + " = " + (rangeWins / rangeMatchups));
            result.AppendLine("total = " + (totalWins / totalMatchups));
        }
        private void ReportRange(StringBuilder result, Hand hand, IRange manyHands, IRange range)
        {
            // This is how you get the weight of a hand from range
            double weightForSingleHand = range[hand];

            double totalCombinationsInSelectedSubRange = 0;

            // This is how you can iterate over all hands in a range
            foreach (Hand singleConbination in manyHands)
            {
                totalCombinationsInSelectedSubRange += manyHands[singleConbination];
            }

            //This is a shortcut to get the sum of all weights
            double totalWeightsInRange = range.TotalWeights();

            result.AppendLine("Weight for single hand  " + hand.ToUnicodeString() + " = " + weightForSingleHand);
            result.AppendLine("Summary weight for hands " + manyHands.ToSingleLineString() + " = " + totalCombinationsInSelectedSubRange);
            result.AppendLine("Total combos in range = " + totalWeightsInRange);
        }