/// <summary>
        /// Calculate the odds for low for the given list of players.
        /// </summary>
        /// <param name="players"></param>
        /// <param name="calculateAt"></param>
        /// <param name="boardCards"></param>
        /// <param name="undealtCards"></param>
        public virtual void CalculateOddsForLow(ref List <Player> players, OddsCalculationTime calculateAt, List <Card> boardCards, List <Card> undealtCards)
        {
            if (calculateOddsForLow)
            {
                Validate(ref players, calculateAt, boardCards);
            }
            else
            {
                throw new NotSupportedException("The selected game does not support calculating odds for low.");
            }
            switch ((int)calculateAt)
            {
            case (int)OddsCalculationTime.OnFlop:
                DetermineWinnerOnFlop(ref players, boardCards, undealtCards, WinType.Low);
                break;

            case (int)OddsCalculationTime.OnTurn:
                DetermineWinnerOnTurn(ref players, boardCards, undealtCards, WinType.Low);
                break;

            case (int)OddsCalculationTime.OnRiver:
                DetermineWinnerOnRiver(ref players, boardCards, undealtCards, WinType.Low);
                break;

            default:
                throw new ArgumentException("Invalid value for Calculation time.");
            }
            SetWinOddsForEachPlayers(players, WinType.Low);
        }
 public override void OverallEquity(ref List <Player> players, OddsCalculationTime calculateAt, List <Card> boardCards, List <Card> undealtCards)
 {
     Validate(players, calculateAt, boardCards, undealtCards);
     //rework so we can iterate over the player and cards only once when both.
     base.CalculateOddsForLow(ref players, calculateAt, boardCards, undealtCards);
     base.CalculateOddsForHigh(ref players, calculateAt, boardCards, undealtCards);
 }
        private void Validate(List <Player> players, OddsCalculationTime calulcateAt, List <Card> boardCards, List <Card> undealtCards)
        {
            foreach (Player player in players)
            {
                if (player.PlayerCards.Count() != 4)
                {
                    throw new ArgumentException("Each player should have four cards. Invalid data for player " + player.PlayerNo);
                }
            }
            int totalPlayerCards = players.Count * 4;

            if (totalPlayerCards + boardCards.Count + undealtCards.Count != CardDeck.NUMBEROFCARDSINDECK)
            {
                throw new ArgumentException("Invalid number of cards. Total cards do not add upto " + CardDeck.NUMBEROFCARDSINDECK);
            }
        }
        public virtual void CalculateOddsForHigh(ref List <Player> players, OddsCalculationTime calculateAt, List <Card> boardCards, List <Card> undealtCards)
        {
            Validate(ref players, calculateAt, boardCards);
            switch ((int)calculateAt)
            {
            case (int)OddsCalculationTime.OnFlop:
                DetermineWinnerOnFlop(ref players, boardCards, undealtCards, WinType.High);
                break;

            case (int)OddsCalculationTime.OnTurn:
                DetermineWinnerOnTurn(ref players, boardCards, undealtCards, WinType.High);
                break;

            case (int)OddsCalculationTime.OnRiver:
                DetermineWinnerOnRiver(ref players, boardCards, undealtCards, WinType.High);
                break;

            default:
                throw new ArgumentException("Invalid value for Calculation time.");
            }
        }
 public virtual void OverallEquity(ref List <Player> players, OddsCalculationTime calculateAt, List <Card> boardCards, List <Card> undealtCards)
 {
     Validate(ref players, calculateAt, boardCards);
 }
        private void Validate(ref List <Player> players, OddsCalculationTime calculateAt, List <Card> boardCards)
        {
            if (players == null || players.Count == 0)
            {
                throw new ArgumentNullException("Please pass information about players");
            }
            if (calculateAt != OddsCalculationTime.PreFlop && (boardCards == null || boardCards.Count == 0))
            {
                throw new ArgumentNullException("Pass board card(s) for calculating odds.");
            }
            if (players.Count == 0)
            {
                throw new ArgumentException("Atleast one player is required.");
            }
            if (players.Count > 0)
            {
                int cardsPerPlayer = -1;
                for (int i = 0; i < players.Count; i++)
                {
                    Player plr = players[i];

                    if (plr.PlayerCards == null)
                    {
                        throw new ArgumentNullException(String.Format("Players Cards cannot be empty.Check cards for {0}", plr.PlayerNo));
                    }
                    if (i == 0)
                    {
                        cardsPerPlayer = plr.PlayerCards.Length;
                    }
                    if (cardsPerPlayer != plr.PlayerCards.Length)
                    {
                        throw new ArgumentException(String.Format("All players must have the same number of cards. Check cards for Player{0}", plr.PlayerNo));
                    }
                    HashSet <Card> playerCardsUnique = new HashSet <Card>();
                    for (int z = 0; z < plr.PlayerCards.Length; z++)
                    {
                        if (playerCardsUnique.Contains(plr.PlayerCards[z]))
                        {
                            //show the card in the future??
                            throw new ArgumentException(string.Format("Please check the player {0}'s cards. Duplicates are not allowed.", z + 1));
                        }
                        else
                        {
                            playerCardsUnique.Add(plr.PlayerCards[z]);
                        }
                    }
                    for (int b = 0; b < boardCards.Count; b++)
                    {
                        if (playerCardsUnique.Contains(boardCards[b]))
                        {
                            //show the card in the future??boardCards[b].Rank + boardCards[b].Suit
                            throw new ArgumentException("Please check the board cards. Duplicates are not allowed.");
                        }
                        else
                        {
                            playerCardsUnique.Add(boardCards[b]);
                        }
                    }
                }
            }
        }
 public override void CalculateOddsForHigh(ref List <Player> players, OddsCalculationTime calculateAt, List <Card> boardCards, List <Card> undealtCards)
 {
     Validate(players, calculateAt, boardCards, undealtCards);
     base.CalculateOddsForHigh(ref players, calculateAt, boardCards, undealtCards);
 }
 public override void CalculateOddsForLow(ref List <Player> players, OddsCalculationTime calculateAt, List <Card> boardCards, List <Card> undealtCards)
 {
     throw new NotSupportedException("Calculating low is not allowed for Omaha High games");
 }