private void game_PlayerActed(Guid playerId, ActionType action, int amountToCall, int amount) { var actionBucket = ActionAbstracter.MapToBucket(action, amountToCall, currentGame.PotSize, amount); actionHistory.Add(actionBucket); FeatureAction featureAction = FeatureActionAbstracter.FromActionBucket(actionBucket); var currentPhasehistory = actionHistoriesPerPhase.FirstOrDefault(x => x.Phase == currentGame.Phase); currentPhasehistory.ActionHistory.Add(featureAction); if (this.Id != playerId) { Positioning opponentPositioning = Positioning.None; Aggression opponentAggression = Aggression.None; if (currentGame.Phase > GamePhase.PreFlop) { opponentPositioning = getOpponentPositioning(currentPhasehistory.ActionHistory.Count); opponentAggression = getOpponentAggression(opponentPositioning); } opponent.UpdateFeaturesAfterAction(currentPhasehistory.ActionHistory, currentGame.Phase, opponentAggression, opponentPositioning); } }
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 })); } }