public double CalculateOuts(IEnumerable<Card> playerCards, IEnumerable<Card> cards) { var deck = new List<Card>(); for (int i = 0; i <= 3; i++) { for (int j = 2; j <= 14; j++) { deck.Add(new Card((CardSuit)i, (CardType)j)); } } List<Card[]> pairsCombos = new List<Card[]>(); for (int i = 0; i < deck.Count; i++) { for (int j = 0; j < deck.Count; j++) { if (i != j) { pairsCombos.Add(new Card[2] { deck[i], deck[j] }); } } } HashSet<Card> board = new HashSet<Card>(cards); var handEvaluator = new HandEvaluator(); var myPlayerCards = new HashSet<Card>(); foreach (var card in playerCards) { myPlayerCards.Add(card); } foreach (var card in board) { myPlayerCards.Add(card); } var handEvaluatorExtended = new HandEvaluatorExtension(); var bestHandFromBoard = handEvaluatorExtended.GetBestHandForFlop(board); var playerBestHand = handEvaluator.GetBestHand(myPlayerCards); if (playerBestHand.RankType <= bestHandFromBoard.RankType && (cards.ToList().Count() == 3)) { return 21; } if (cards.Count() == 4 && cards.Any()) { var bestHandFromBoardOnTurn = handEvaluatorExtended.GetBestHandForTurn(board); if (playerBestHand.RankType <= bestHandFromBoardOnTurn.RankType) { return 21; } } long wins = 0, ties = 0, loses = 0, count = 0; // Iterate through all possible opponent hole cards // This is one because it is very slow otherwise. // I have tested it and there is not much of a difference for (var i = 0; i < 1; i++) { var otherHand = new HashSet<Card>(); foreach (var pairsCombo in pairsCombos) { foreach (var card in pairsCombo) { otherHand.Add(card); } foreach (var card in board) { otherHand.Add(card); } if (otherHand.Count < 5) { continue; } var otherBestHand = handEvaluator.GetBestHand(otherHand); if (playerBestHand.RankType > otherBestHand.RankType) { wins++; } else if (playerBestHand.RankType == otherBestHand.RankType) { ties++; } else { loses++; } count++; otherHand.Clear(); } } var percent = (((double)wins) + ((double)ties) / 2.0) / ((double)count) * 100.0; return percent; }
private PlayerAction GetActionForFlop(GetTurnContext context) { var playHand = HandStrengthValuation.Flop(this.FirstCard, this.SecondCard, this.CommunityCards); if (playHand == CardValuationType.Unplayable) { if (context.CanCheck) { return PlayerAction.CheckOrCall(); } return PlayerAction.Fold(); } if (playHand == CardValuationType.Risky) { if (context.CanCheck) { return PlayerAction.CheckOrCall(); } return PlayerAction.Fold(); } HandEvaluatorExtension handEvaluator = new HandEvaluatorExtension(); var cards = new List<Card>(); cards.AddRange(this.CommunityCards); cards.Add(this.FirstCard); cards.Add(this.SecondCard); var handsInCommunity = handEvaluator.GetBestHandForFlop(cards); if (handsInCommunity.RankType == HandRankType.Pair) { if (this.FirstCard.Type < CardType.Ten && this.SecondCard.Type < CardType.Ten) { return PlayerAction.Fold(); } } if (playHand == CardValuationType.Recommended) { var smallBlindsTimes = RandomProvider.Next(1, 14); if (context.CanCheck) { if (context.MoneyToCall <= context.MoneyLeft / 10) { return PlayerAction.CheckOrCall(); } return PlayerAction.Fold(); } if (this.raisesOnFlop < 2) { this.raisesOnPreFlop += 1; return PlayerAction.Raise(context.SmallBlind * smallBlindsTimes); } return PlayerAction.CheckOrCall(); } if (playHand == CardValuationType.StronglyRecommended) { if (this.raisesOnFlop < 1) { this.raisesOnPreFlop += 1; return PlayerAction.Raise(context.SmallBlind * 4); } else { return PlayerAction.Fold(); } } return PlayerAction.CheckOrCall(); }