Beispiel #1
0
        /// <summary>
        /// <para>This method calculates chances of our hand to win and based on the results returns values, which to be used for decisionmaking</para>
        /// <para>Used methods to calculate chances:</para>
        ///     <para>-> for pre-flop: uses the gap parameter and checkes wether we have High Card or a Pair</para>
        ///     <para>-> for all other rounds: uses MonteCarlo algorythm on 250 game trials, which is with diff: (3 to 2.5)</para>
        /// </summary>
        /// <param name="ourCards"><c>string</c> that contains our cards <example>example: "2h 3h"</example></param>
        /// <param name="communityCards"><c>string</c> that contains the community cards <example>example: "Jh Qh 2d"</example></param>
        /// <param name="currentRound"><c>GameRoundType</c> is enum that informs us in which round are we currently playing <example>example: GameRoundType.PreFlop</example></param>
        /// <param name="gapBetweenOurCards"><c>int</c> that informs us what is the gap between the cards in our hand
        /// <example>example: If we have Jack and 8 -> gap = 2,
        /// If we have King and 6 -> gap = 6</example></param>
        /// <returns><c>Turn</c> object that holds the chance values for Fold, Call, Raise and AllIn</returns>
        /// <seealso cref="http://www.codeproject.com/Articles/19092/More-Texas-Holdem-Analysis-in-C-Part-2"/>
        public Turn DecideChanceForAction(string ourCards, string communityCards, GameRoundType currentRound, int gapBetweenOurCards)
        {
            var output  = new Turn();
            var ourHand = new Hand(ourCards, communityCards);
            int chance  = 0;

            switch (currentRound)
            {
            case GameRoundType.PreFlop:
                if (gapBetweenOurCards >= 4)
                {
                    this.Call++;
                    this.Fold++;
                }
                else if (gapBetweenOurCards >= 2)
                {
                    this.Raise++;
                    this.Call++;
                }
                else
                {
                    this.AllIn++;
                    this.Raise++;
                }

                var handTypeValue = ourHand.HandTypeValue;
                switch (handTypeValue)
                {
                case Hand.HandTypes.HighCard:
                    this.Raise++;
                    this.Call++;
                    break;

                case Hand.HandTypes.Pair:
                    this.AllIn++;
                    this.Raise++;
                    this.Call++;
                    break;

                default:
                    this.Raise++;
                    this.Call++;
                    this.Fold++;
                    break;
                }

                break;

            case GameRoundType.Flop:
                chance = MonteCarloAnalysis.WinOddsMonteCarlo(ourCards, communityCards);
                if (chance > 16 && chance <= 34)
                {
                    this.Call++;
                    this.Fold++;
                }
                else if (chance > 34 && chance <= 40)
                {
                    this.Raise++;
                    this.Call++;
                }
                else if (chance > 40 && chance <= 51)
                {
                    this.AllIn++;
                    this.Raise++;
                    this.Call++;
                }
                else if (chance > 51)
                {
                    this.AllIn++;
                    this.Raise++;
                }
                else
                {
                    this.Fold++;
                }

                break;

            case GameRoundType.Turn:
                chance = MonteCarloAnalysis.WinOddsMonteCarlo(ourCards, communityCards);
                if (chance > 18 && chance <= 34)
                {
                    this.Call++;
                    this.Fold++;
                }
                else if (chance > 34 && chance <= 41)
                {
                    this.Raise++;
                    this.Call++;
                }
                else if (chance > 41 && chance <= 55)
                {
                    this.AllIn++;
                    this.Raise++;
                    this.Call++;
                }
                else if (chance > 55)
                {
                    this.AllIn++;
                    this.Raise++;
                }
                else
                {
                    this.Fold++;
                }

                break;

            case GameRoundType.River:
                chance = MonteCarloAnalysis.WinOddsMonteCarlo(ourCards, communityCards);
                if (chance > 20 && chance <= 36)
                {
                    this.Call++;
                    this.Fold++;
                }
                else if (chance > 36 && chance <= 45)
                {
                    this.Raise++;
                    this.Call++;
                }
                else if (chance > 45 && chance <= 62)
                {
                    this.AllIn++;
                    this.Raise++;
                    this.Call++;
                }
                else if (chance > 62)
                {
                    this.AllIn++;
                    this.Raise++;
                }
                else
                {
                    this.Fold++;
                }

                break;
            }

            return(output);
        }
Beispiel #2
0
        public override PlayerAction GetTurn(GetTurnContext context)
        {
            #region PreFlopLogic
            if (context.RoundType == GameRoundType.PreFlop)
            {
                //checks if we have the button
                if (context.MyMoneyInTheRound == context.SmallBlind)
                {
                    hasTheButton = true;
                }
                //checks if 3bettedPot; If the pot is big it is!
                if (context.CurrentPot > (context.SmallBlind * 4))
                {
                    is3bettedPot = true;
                }

                var playHand = HandStrengthValuation.PreFlop(this.FirstCard, this.SecondCard, hasTheButton);


                //http://www.holdemresources.net/h/poker-theory/hune/usage.html

                #region mFactor< 20
                if (mFactor < 20)
                {
                    double nashEquillibriumRatio = 0;

                    if (hasTheButton)
                    {
                        nashEquillibriumRatio = HandStrengthValuation.GetPusherBlindsCount(this.FirstCard, this.SecondCard);
                    }
                    else
                    {
                        nashEquillibriumRatio = HandStrengthValuation.GetCallerBlindsCount(this.FirstCard, this.SecondCard);
                    }

                    //find if we have less money then the effective stack size
                    bool push = context.MoneyLeft <= (nashEquillibriumRatio * (context.SmallBlind * 2));

                    if (push)
                    {
                        return(PlayerAction.Raise(context.CurrentMaxBet));
                    }
                    else
                    {
                        if (context.CanCheck)
                        {
                            return(PlayerAction.CheckOrCall());
                        }
                        else
                        {
                            return(PlayerAction.Fold());
                        }
                    }
                }
                #endregion

                #region UnplayableHands
                if (playHand == CardValuationType.Unplayable)
                {
                    if (context.CanCheck)
                    {
                        return(PlayerAction.CheckOrCall());
                    }
                    else
                    {
                        return(PlayerAction.Fold());
                    }
                }
                #endregion

                // raises risky hands only if in position and if it is not a 3betted Pot
                if (playHand == CardValuationType.Risky && context.MyMoneyInTheRound == context.SmallBlind)
                {
                    //   var smallBlindsTimes = RandomProvider.Next(1, 8);
                    return(PlayerAction.Raise(context.SmallBlind * 6));
                }

                // folds if not in position
                else if (playHand == CardValuationType.Risky && !hasTheButton)
                {
                    if (context.CanCheck)
                    {
                        return(PlayerAction.CheckOrCall());
                    }
                    else
                    {
                        return(PlayerAction.Fold());
                    }
                }

                // if recommended and not in 3bettedPot and a big M RAISES
                if (playHand == CardValuationType.Recommended)
                {
                    if (is3bettedPot && mFactor > 100)
                    {
                        return(PlayerAction.CheckOrCall());
                    }

                    if (is3bettedPot && mFactor > 200)
                    {
                        return(PlayerAction.Fold());
                    }
                    // var smallBlindsTimes = RandomProvider.Next(6, 10);
                    return(PlayerAction.Raise(context.SmallBlind * 6));
                }
                //needs refactoring
                if (playHand == CardValuationType.Premium || playHand == CardValuationType.TopPremium)
                {
                    if (playHand == CardValuationType.TopPremium)
                    {
                        hasTopPremium = true;
                        return(PlayerAction.Raise(context.SmallBlind * 10));
                    }

                    if (playHand == CardValuationType.Premium)
                    {
                        return(PlayerAction.Raise(context.SmallBlind * 10));
                    }
                }

                // not sure if this doesn't brake everything
                if (context.CanCheck)
                {
                    return(PlayerAction.CheckOrCall());
                }
                // not sure if this doesn't brake everything
                else
                {
                    return(PlayerAction.Fold());
                }
            }
            #endregion


            #region Post-FlopLogic

            double currentPotRaise    = context.CurrentPot * 0.55;
            int    currentPotRaiseInt = (int)currentPotRaise;

            List <Card> allCards = new List <Card>(this.CommunityCards);
            allCards.Add(this.FirstCard);
            allCards.Add(this.SecondCard);
            HandRankType type             = HandEvaluator.GetBestHand(allCards).RankType;
            var          playerFirstHand  = ParseHandToString.GenerateStringFromCard(this.FirstCard);
            var          playerSecondHand = ParseHandToString.GenerateStringFromCard(this.SecondCard);

            string playerHand = playerFirstHand + " " + playerSecondHand;
            string openCards  = string.Empty;

            foreach (var item in this.CommunityCards)
            {
                openCards += ParseHandToString.GenerateStringFromCard(item) + " ";
            }

            var chance = MonteCarloAnalysis.CalculateWinChance(playerHand, openCards.Trim());

            int Check = 15;

            int Raise = 60;

            int AllIn = 85;
            if (context.MoneyToCall <= (context.SmallBlind * 2))
            {
                return(PlayerAction.CheckOrCall());
            }

            if (chance < Check)
            {
                return(PlayerAction.Fold());
            }
            if (chance < Raise)
            {
                return(PlayerAction.CheckOrCall());
            }
            else if (chance < AllIn)
            {
                if ((int)type >= (int)HandRankType.Pair)
                {
                    return(PlayerAction.Raise(currentPotRaiseInt));
                }
                else
                {
                    return(PlayerAction.Raise(context.SmallBlind * 4));
                }
            }
            else
            {
                return(PlayerAction.Raise(context.CurrentMaxBet));
            }
        }