Пример #1
0
        public override Task <GameActionEntity> GetAction(List <ActionType> possibleActions, int amountToCall)
        {
            var possibleFeatureActions = new List <FeatureAction>();

            foreach (var possibleAction in possibleActions)
            {
                var featureAction = FeatureActionAbstracter.FromActionType(possibleAction);
                if (!possibleFeatureActions.Contains(featureAction))
                {
                    possibleFeatureActions.Add(featureAction);
                }
            }

            var         currentPhasehistory = actionHistoriesPerPhase.FirstOrDefault(x => x.Phase == currentGame.Phase);
            Positioning opponentPositioning = Positioning.None;
            Aggression  opponentAggression  = Aggression.None;

            if (currentGame.Phase > GamePhase.PreFlop)
            {
                opponentPositioning = getOpponentPositioning(currentPhasehistory.ActionHistory.Count);
                opponentAggression  = getOpponentAggression(opponentPositioning);
            }

            var          counterAction        = opponent.GetCounterAction(possibleFeatureActions, currentPhasehistory.ActionHistory, currentGame.Phase, opponentAggression, opponentPositioning);
            ActionBucket selectedActionBucket = ActionBucket.None;

            if (counterAction == null)
            {
                if (currentGame.Phase == GamePhase.PreFlop)
                {
                    switch (opponent.PlayStyle)
                    {
                    case PlayStyle.LooseAggressive:
                    case PlayStyle.LoosePassive:
                        if (this.IsBigBlind)
                        {
                            selectedActionBucket = ActionBucket.LowBet;
                        }
                        else
                        {
                            if (startHandBucket >= StartHandBucket.VeryBad)
                            {
                                selectedActionBucket = ActionBucket.LowBet;
                            }
                            else
                            {
                                selectedActionBucket = ActionBucket.Pass;
                            }
                        }

                        break;

                    case PlayStyle.TightAggressive:
                    case PlayStyle.TightPassive:
                        //play hyper aggressive
                        selectedActionBucket = ActionBucket.LowBet;
                        break;
                    }
                }
                else
                {
                    switch (opponent.PlayStyle)
                    {
                    case PlayStyle.LooseAggressive:
                        //play TightAggressive
                        if (handStrengthBucket >= HandStrengthBucket.HighCardAce)
                        {
                            selectedActionBucket = ActionBucket.LowBet;
                        }
                        else
                        {
                            selectedActionBucket = ActionBucket.Pass;
                        }
                        break;

                    case PlayStyle.LoosePassive:
                        selectedActionBucket = ActionBucket.LowBet;
                        break;

                    case PlayStyle.TightAggressive:
                        //play LooseAggressive
                        if (handStrengthBucket >= HandStrengthBucket.LowPair)
                        {
                            selectedActionBucket = ActionBucket.LowBet;
                        }
                        else
                        {
                            selectedActionBucket = ActionBucket.Pass;
                        }
                        break;

                    case PlayStyle.TightPassive:
                        //play LooseAggressive
                        if (handStrengthBucket >= HandStrengthBucket.HighCardElse)
                        {
                            selectedActionBucket = ActionBucket.LowBet;
                        }
                        else
                        {
                            selectedActionBucket = ActionBucket.Pass;
                        }
                        break;
                    }
                }
            }
            else
            {
                if (currentGame.Phase == GamePhase.PreFlop)
                {
                    switch (counterAction)
                    {
                    case FeatureAction.Bet:
                        if (startHandBucket > StartHandBucket.Worst)
                        {
                            selectedActionBucket = ActionBucket.LowBet;
                        }
                        break;

                    case FeatureAction.Pass:
                        if (startHandBucket < StartHandBucket.Bad)
                        {
                            selectedActionBucket = ActionBucket.Pass;
                        }
                        break;
                    }
                }
                else
                {
                    switch (counterAction)
                    {
                    case FeatureAction.Bet:
                        selectedActionBucket = ActionBucket.LowBet;
                        break;

                    case FeatureAction.Pass:
                        if (handStrengthBucket < HandStrengthBucket.LowPair)
                        {
                            selectedActionBucket = ActionBucket.Pass;
                        }
                        break;
                    }
                }
            }

            switch (selectedActionBucket)
            {
            case ActionBucket.None:
                //no counter move has been found. Fall back to randomness
                randomBot.ChipStack = this.ChipStack;
                return(randomBot.GetAction(possibleActions, amountToCall));

            default:
                ActionType selectedAction = ActionAbstracter.MapToAction(selectedActionBucket, amountToCall);
                int        betSize        = 0;
                switch (selectedAction)
                {
                case ActionType.Bet:
                case ActionType.Raise:
                    betSize = ActionAbstracter.GetBetSize(selectedActionBucket, amountToCall, currentGame.PotSize);
                    break;

                case ActionType.Call:
                    betSize = amountToCall;
                    break;
                }


                if (!possibleActions.Contains(selectedAction))
                {
                    switch (selectedAction)
                    {
                    case ActionType.Bet:
                    case ActionType.Raise:
                    case ActionType.Check:
                        if (possibleActions.Contains(ActionType.Call))
                        {
                            selectedAction = ActionType.Call;
                        }
                        break;

                    default:
                        throw new Exception("Selected action is illegal!");
                    }
                }

                if (ChipStack < betSize)
                {
                    betSize = this.ChipStack;
                }

                return(Task.FromResult <GameActionEntity>(
                           new GameActionEntity
                {
                    ActionType = selectedAction,
                    Amount = betSize,
                    PlayerId = this.Id
                }));
            }
        }
Пример #2
0
        public override Task <GameActionEntity> GetAction(List <ActionType> possibleActions, int amountToCall)
        {
            var infoSet = new InformationSet <ActionBucket>();

            infoSet.ActionHistory = actionHistory;
            infoSet.CardBucket    = handBucket;

            RegretGameNode <ActionBucket> gameNode;

            trainedTree.TryGetValue(infoSet.GetLongHashCode(), out gameNode);
            if (gameNode == null)
            {
                // this should never occur
                randomBot.ChipStack = this.ChipStack;
                return(randomBot.GetAction(possibleActions, amountToCall));
            }
            else
            {
                var    optimalStrategy     = gameNode.calculateAverageStrategy();
                var    rand                = new Random();
                double randomValue         = rand.NextDouble();
                bool   isCallActionEnabled = (optimalStrategy.Count == 5);

                int          index                = 0;
                double       sumPercent           = 0;
                ActionBucket selectedActionBucket = ActionBucket.None;
                foreach (ActionBucket action in Enum.GetValues(typeof(ActionBucket)))
                {
                    if (action == ActionBucket.None)
                    {
                        continue;
                    }
                    if (action == ActionBucket.Call && !isCallActionEnabled)
                    {
                        continue;
                    }

                    double newSumPercent = sumPercent + optimalStrategy[index];
                    if (randomValue >= sumPercent && randomValue <= newSumPercent)
                    {
                        selectedActionBucket = action;
                        break;
                    }

                    sumPercent = newSumPercent;
                    index++;
                }

                ActionType selectedAction = ActionAbstracter.MapToAction(selectedActionBucket, amountToCall);
                int        betSize        = 0;
                switch (selectedAction)
                {
                case ActionType.Bet:
                case ActionType.Raise:
                    betSize = ActionAbstracter.GetBetSize(selectedActionBucket, amountToCall, currentGame.PotSize);
                    break;

                case ActionType.Call:
                    betSize = amountToCall;
                    break;
                }


                if (!possibleActions.Contains(selectedAction))
                {
                    // in all-in scenarios actions from bot may differ from possible actions
                    switch (selectedAction)
                    {
                    case ActionType.Bet:
                    case ActionType.Raise:
                    case ActionType.Check:
                        if (possibleActions.Contains(ActionType.Call))
                        {
                            selectedAction = ActionType.Call;
                        }
                        break;

                    default:
                        throw new Exception("Selected action is illegal!");
                    }
                }

                if (ChipStack < betSize)
                {
                    betSize = this.ChipStack;
                }

                return(Task.FromResult <GameActionEntity>(new GameActionEntity
                {
                    ActionType = selectedAction,
                    Amount = betSize,
                    PlayerId = this.Id
                }));
            }
        }
        public override Task <GameActionEntity> GetAction(List <ActionType> possibleActions, int amountToCall)
        {
            ActionBucket selectedActionBucket;

            switch (currentGame.Phase)
            {
            case GamePhase.PreFlop:
                double startHandStrengthRatio = (double)startHandBucket / (double)StartHandBucket.Best;
                if (TightRatio <= startHandStrengthRatio)
                {
                    startHandStrengthRatio = 1 - startHandStrengthRatio;
                    if (AggressiveRatio >= startHandStrengthRatio)
                    {
                        selectedActionBucket = ActionBucket.LowBet;
                    }
                    else
                    {
                        selectedActionBucket = ActionBucket.Call;
                    }
                }
                else
                {
                    selectedActionBucket = ActionBucket.Pass;
                }
                break;

            default:
                double handStrengthRatio = 1 - (double)handStrengthBucket / (double)HandStrengthBucket.TopHands;
                if (AggressiveRatio >= handStrengthRatio)
                {
                    selectedActionBucket = ActionBucket.LowBet;
                }
                else
                {
                    selectedActionBucket = ActionBucket.Pass;
                }

                break;
            }

            ActionType selectedAction = ActionAbstracter.MapToAction(selectedActionBucket, amountToCall);
            int        betSize        = 0;

            switch (selectedAction)
            {
            case ActionType.Bet:
            case ActionType.Raise:
                betSize = ActionAbstracter.GetBetSize(selectedActionBucket, amountToCall, currentGame.PotSize);
                break;

            case ActionType.Call:
                betSize = amountToCall;
                break;
            }

            if (!possibleActions.Contains(selectedAction))
            {
                switch (selectedAction)
                {
                case ActionType.Bet:
                case ActionType.Raise:
                case ActionType.Check:
                    if (possibleActions.Contains(ActionType.Call))
                    {
                        selectedAction = ActionType.Call;
                    }
                    break;

                case ActionType.Call:
                    if (possibleActions.Contains(ActionType.Check))
                    {
                        selectedAction = ActionType.Check;
                    }
                    break;

                default:
                    throw new Exception("Selected action is illegal!");
                }
            }

            if (ChipStack < betSize)
            {
                betSize = this.ChipStack;
            }

            return(Task.FromResult <GameActionEntity>(
                       new GameActionEntity
            {
                ActionType = selectedAction,
                Amount = betSize,
                PlayerId = this.Id
            }));
        }