void handHistoryParser_PlayerBet(string playerName, float amount, HoldemGamePhase gamePhase) { HoldemPlayer p = (HoldemPlayer)FindPlayer(playerName); if (p == null) { Trace.WriteLine("Bet detected but the player is not in our list. Did he just join?"); return; } // Flop if (gamePhase == HoldemGamePhase.Flop && !PlayerBetTheFlop) { // Did he raised preflop? if (p.HasPreflopRaisedThisRound()) { p.IncrementOpportunitiesToCBet(true); PlayerCBet = true; } PlayerBetTheFlop = true; } p.HasBet(gamePhase); }
void handHistoryParser_PlayerChecked(string playerName, HoldemGamePhase gamePhase) { HoldemPlayer p = (HoldemPlayer)FindPlayer(playerName); // On some clients, a player who is sitting out might be automatically made to check if (p == null) { Trace.WriteLine("Check detected but the player is not in our list. Is he sitting out?"); return; } if (gamePhase == HoldemGamePhase.Preflop) { /* Steal raise opportunity */ if (p.IsButton && !PlayerRaisedPreflop && !PlayerLimpedPreflop && !PlayerCheckedPreflop) { p.IncrementOpportunitiesToStealRaise(); } PlayerCheckedPreflop = true; } // Flop if (gamePhase == HoldemGamePhase.Flop && !PlayerBetTheFlop && p.HasPreflopRaisedThisRound()) { p.IncrementOpportunitiesToCBet(false); } p.HasChecked(gamePhase); }
protected void OnPlayerRaised(String playerName, float raiseAmount, HoldemGamePhase gamePhase) { if (PlayerRaised != null) { PlayerRaised(playerName, raiseAmount, gamePhase); } }
protected void OnPlayerChecked(String playerName, HoldemGamePhase gamePhase) { if (PlayerChecked != null) { PlayerChecked(playerName, gamePhase); } }
protected void OnPlayerPushedAllIn(String playerName, HoldemGamePhase gamePhase) { if (PlayerPushedAllIn != null) { PlayerPushedAllIn(playerName, gamePhase); } }
void HoldemTableStatistics_PlayerPushedAllIn(string playerName, HoldemGamePhase gamePhase) { HoldemPlayer p = (HoldemPlayer)FindPlayer(playerName); Trace.WriteLine("Pushed all-in: " + p.Name); p.HasPushedAllIn(gamePhase); }
protected void OnPlayerCalled(String playerName, float amount, HoldemGamePhase gamePhase) { if (PlayerCalled != null) { PlayerCalled(playerName, amount, gamePhase); } }
private Statistic CreateOutsStatistic(String name, int numOuts, HoldemGamePhase phase) { Trace.Assert(phase == HoldemGamePhase.Flop || phase == HoldemGamePhase.Turn, "Cannot create outs statistics for a phase different than flop or turn."); float value = 0.0f; if (phase == HoldemGamePhase.Flop) { value = GetOutsPercentage(numOuts, OutsByThe.Turn); } else if (phase == HoldemGamePhase.Turn) { value = GetOutsPercentage(numOuts, OutsByThe.River); } Statistic result = new Statistic(new StatisticsOddsData(name, value, PRECISION)); // The flop has extra information as we want to see the chances of hitting // something by the turn, or by the turn and river combined if (phase == HoldemGamePhase.Flop) { float valueByTurnOrRiver = GetOutsPercentage(numOuts, OutsByThe.TurnOrRiver); result.AddSubStatistic(new StatisticsOddsData("By the turn", value, PRECISION)); result.AddSubStatistic(new StatisticsOddsData("By the turn or river", valueByTurnOrRiver, PRECISION)); } return(result); }
private void SetupNewRound() { PlayerHasShowedThisRound = false; ShowdownEventRaised = false; boardCards.Clear(); playerSeats.Clear(); currentGamePhase = HoldemGamePhase.Preflop; }
void handHistoryParser_PlayerCalled(string playerName, float amount, HoldemGamePhase gamePhase) { HoldemPlayer p = (HoldemPlayer)FindPlayer(playerName); if (p == null) { Trace.WriteLine("Call detected but the player is not in our list. Did he just join?"); return; } // If we are preflop if (gamePhase == HoldemGamePhase.Preflop) { // If the call is the same amount as the big blind, this is also a limp if (amount == BigBlindAmount) { PlayerLimpedPreflop = true; // HasLimped() makes further checks to avoid duplicate counts and whether the player is the big blind or small blind p.CheckForLimp(); } /* Steal raise opportunity */ if (p.IsButton && !PlayerRaisedPreflop && !PlayerLimpedPreflop && !PlayerCheckedPreflop) { p.IncrementOpportunitiesToStealRaise(); } /* Called a steal raise? */ else if (p.IsSmallBlind && PlayerStealRaisedPreflop) { p.IncrementCallsToAStealRaise(); } else if (p.IsBigBlind && PlayerStealRaisedPreflop && !SmallBlindReraisedAStealRaise) { p.IncrementCallsToAStealRaise(); } /* From the blind called a raise (but NOT to a reraise) ? */ if (p.IsBlind() && PlayerRaisedPreflop && !PlayerReRaisedPreflop) { p.IncrementCallsBlindToAPreflopRaise(); } } else if (gamePhase == HoldemGamePhase.Flop) { // Has somebody cbet? if (!PlayerRaisedTheFlop && PlayerCBet) { p.IncrementCallToACBet(); } } p.HasCalled(gamePhase); }
/* Calculates the type of the hand given a board * during a game phase */ public HoldemHand.Classification GetClassification(HoldemGamePhase phase, HoldemBoard board) { if (phase == HoldemGamePhase.Preflop) { return(new ClassificationPreflop(this)); } else { return(new ClassificationPostflop(this, phase, board)); } }
public HoldemBoard GetBoardAt(HoldemGamePhase phase) { switch (phase) { case HoldemGamePhase.Flop: return new HoldemBoard(cards[0], cards[1], cards[2]); case HoldemGamePhase.Turn: Trace.Assert(cards.Count >= 4, "Trying to get turn board when only flop cards are available"); return new HoldemBoard(cards[0], cards[1], cards[2], cards[3]); case HoldemGamePhase.River: Trace.Assert(cards.Count >= 5, "Trying to get river board when only flop or cards are available"); return new HoldemBoard(cards[0], cards[1], cards[2], cards[3], cards[4]); default: Trace.Assert(false, "Trying to get a board for an invalid game phase"); return null; } }
void handHistoryParser_PlayerFolded(string playerName, HoldemGamePhase gamePhase) { HoldemPlayer p = (HoldemPlayer)FindPlayer(playerName); // On some clients, even if the player is sitting out they will make him automatically fold if (p == null) { Trace.WriteLine("Fold detected but the player is not in our list... is he sitting out?"); return; } if (gamePhase == HoldemGamePhase.Preflop) { /* Steal raise opportunity */ if (p.IsButton && !PlayerRaisedPreflop && !PlayerLimpedPreflop && !PlayerCheckedPreflop) { p.IncrementOpportunitiesToStealRaise(); } /* Folded to a steal raise? */ else if (p.IsSmallBlind && PlayerStealRaisedPreflop) { p.IncrementFoldsToAStealRaise(); } else if (p.IsBigBlind && PlayerStealRaisedPreflop && !SmallBlindReraisedAStealRaise) { p.IncrementFoldsToAStealRaise(); } /* Folded to a raise (but NOT to a reraise) ? */ if (p.IsBlind() && PlayerRaisedPreflop && !PlayerReRaisedPreflop) { p.IncrementFoldsBlindToAPreflopRaise(); } } // Has somebody cbet? else if (gamePhase == HoldemGamePhase.Flop && !PlayerRaisedTheFlop && PlayerCBet) { p.IncrementFoldToACBet(); } p.HasFolded(gamePhase); }
public HoldemBoard GetBoardAt(HoldemGamePhase phase) { switch (phase) { case HoldemGamePhase.Flop: return(new HoldemBoard(cards[0], cards[1], cards[2])); case HoldemGamePhase.Turn: Trace.Assert(cards.Count >= 4, "Trying to get turn board when only flop cards are available"); return(new HoldemBoard(cards[0], cards[1], cards[2], cards[3])); case HoldemGamePhase.River: Trace.Assert(cards.Count >= 5, "Trying to get river board when only flop or cards are available"); return(new HoldemBoard(cards[0], cards[1], cards[2], cards[3], cards[4])); default: Trace.Assert(false, "Trying to get a board for an invalid game phase"); return(null); } }
protected void OnPlayerRaised(String playerName, float raiseAmount, HoldemGamePhase gamePhase) { if (PlayerRaised != null) PlayerRaised(playerName, raiseAmount, gamePhase); }
public HoldemHand.Classification GetHandClassification(HoldemGamePhase phase, HoldemBoard board) { HoldemHand.Classification classification = GetClassification(phase, board); Trace.WriteLine(String.Format("Rating hand [{0}] for {1} on board [{2}]: {3}", base.ToString(), phase.ToString(), board.ToString(), classification.ToString())); return classification; }
protected void OnPlayerPushedAllIn(String playerName, HoldemGamePhase gamePhase) { if (PlayerPushedAllIn != null) PlayerPushedAllIn(playerName, gamePhase); }
/* How many times has the player folded? */ public Statistic GetFoldsStats(HoldemGamePhase phase, String category) { if (sawStreet[phase].Value == 0) return Statistic.CreateUnknown("Folds", category); else { float foldsRatio = (float)folds[phase].Value / (float)sawStreet[phase].Value; return new Statistic(new StatisticsPercentageData("Folds", foldsRatio), category); } }
/* Has bet */ public void HasBet(HoldemGamePhase gamePhase) { /* We're only interested in the first action */ if (!sawStreet[gamePhase].WasIncremented) { bets[gamePhase].Increment(); } if (gamePhase == HoldemGamePhase.Preflop) { voluntaryPutMoneyPreflop.Increment(); } IncrementStatistics(totalBets, gamePhase); sawStreet[gamePhase].Increment(); }
public HoldemHand.Classification GetHandClassification(HoldemGamePhase phase, HoldemBoard board) { HoldemHand.Classification classification = GetClassification(phase, board); Trace.WriteLine(String.Format("Rating hand [{0}] for {1} on board [{2}]: {3}", base.ToString(), phase.ToString(), board.ToString(), classification.ToString())); return(classification); }
public ClassificationPostflop(HoldemHand hand, HoldemGamePhase phase, HoldemBoard board) { CardList communityCards = board.GetBoardAt(phase); // Default this.hand = HandType.Unknown; this.kicker = KickerType.Unknown; this.pair = PairType.Irrelevant; this.draw = DrawType.Irrelevant; this.straightDraw = StraightDrawType.None; Trace.Assert(communityCards.Count > 0, "Cannot classificate an empty list of community cards."); // Create a new list including the board cards and the cards from the hand CardList cards = new CardList(communityCards.Count + 2); foreach (Card c in communityCards) { cards.AddCard(c); } cards.AddCard(hand.GetFirstCard()); cards.AddCard(hand.GetSecondCard()); // --- Royal flush if (IsRoyalFlush(cards)) { this.hand = HandType.RoyalFlush; this.kicker = KickerType.Irrelevant; return; } // -- Four of a kind if (cards.HaveIdenticalFaces(4)) { this.hand = HandType.FourOfAKind; this.kicker = KickerType.Irrelevant; return; } // -- Full House // If we have three of a kind and two pair at the same time, we have a full house bool isThreeOfAKind = cards.HaveIdenticalFaces(3); bool isTwoPair = IsTwoPair(cards); if (isThreeOfAKind && isTwoPair) { this.hand = HandType.FullHouse; this.kicker = KickerType.Irrelevant; return; } // -- Flush for (int i = 0; i < cards.Count; i++) { int numCardsSameSuit = 0; for (int j = i + 1; j < cards.Count; j++) { if (cards[i].Suit == cards[j].Suit) { numCardsSameSuit++; } } if (numCardsSameSuit >= 4) { this.hand = HandType.Flush; this.kicker = KickerType.Irrelevant; return; } } // -- Straight if (IsStraight(cards)) { this.hand = HandType.Straight; this.kicker = KickerType.Irrelevant; return; } // Calculate draws (if we got until here, there might be some) // Also, no draws are possible at the river if (phase == HoldemGamePhase.River) { draw = DrawType.None; straightDraw = StraightDrawType.None; } else { draw = GetDrawType(cards); if (IsInsideStraightDraw(cards)) { straightDraw = StraightDrawType.InsideStraightDraw; } if (IsOpenEndedStraightDraw(cards)) { straightDraw = StraightDrawType.OpenEndedStraightDraw; } } // -- Trips if (isThreeOfAKind) { this.hand = HandType.ThreeOfAKind; this.kicker = KickerType.Irrelevant; return; } // -- Two pair if (isTwoPair) { this.hand = HandType.TwoPair; this.kicker = KickerType.Irrelevant; return; } // -- Pair Card matching; if (cards.HaveIdenticalFaces(2, out matching)) { // Sort list by face value (ace high first) cards.Sort(SortUsing.AceHigh); // Find kicker (check from end of the list where face values are higher) Card kicker = cards[0]; for (int i = cards.Count - 1; i >= 0; i--) { if (cards[i].Face != matching.Face) { kicker = cards[i]; break; } } this.hand = HandType.Pair; this.kicker = GetKickerTypeFromCard(kicker); this.pair = GetPairType(communityCards, matching, hand.GetFirstCard(), hand.GetSecondCard()); return; } // -- High card cards.Sort(SortUsing.AceHigh); Card highCard = cards.Last; this.hand = HandType.HighCard; this.kicker = GetKickerTypeFromCard(highCard); }
/* @param ratings the multiple value counter object containing the ratings how a check action, can be null if no ratings are available */ private Statistic GetCheckActionStats(HoldemGamePhase phase, String name, String category, MultipleValueCounter values, MultipleValueCounter ratings) { int checkActions = (int)checkRaises[phase].Value + (int)checkCalls[phase].Value + (int)checkFolds[phase].Value; if (checkActions == 0) { if (ratings != null) return CreateUnknownActionStatistic(name, category); else return Statistic.CreateUnknown(name, category); } else { float ratio = (float)values[phase].Value / (float)checkActions; Statistic ret = new Statistic(new StatisticsPercentageData(name, ratio), category); if (ratings != null) AppendActionsSubstatistics(phase, ret, ratings); return ret; } }
private Statistic CreateOutsStatistic(String name, int numOuts, HoldemGamePhase phase) { Trace.Assert(phase == HoldemGamePhase.Flop || phase == HoldemGamePhase.Turn, "Cannot create outs statistics for a phase different than flop or turn."); float value = 0.0f; if (phase == HoldemGamePhase.Flop) { value = GetOutsPercentage(numOuts, OutsByThe.Turn); } else if (phase == HoldemGamePhase.Turn) { value = GetOutsPercentage(numOuts, OutsByThe.River); } Statistic result = new Statistic(new StatisticsOddsData(name, value, PRECISION)); // The flop has extra information as we want to see the chances of hitting // something by the turn, or by the turn and river combined if (phase == HoldemGamePhase.Flop) { float valueByTurnOrRiver = GetOutsPercentage(numOuts, OutsByThe.TurnOrRiver); result.AddSubStatistic(new StatisticsOddsData("By the turn", value, PRECISION)); result.AddSubStatistic(new StatisticsOddsData("By the turn or river", valueByTurnOrRiver, PRECISION)); } return result; }
public ClassificationPostflop(HoldemHand hand, HoldemGamePhase phase, HoldemBoard board) { CardList communityCards = board.GetBoardAt(phase); // Default this.hand = HandType.Unknown; this.kicker = KickerType.Unknown; this.pair = PairType.Irrelevant; this.draw = DrawType.Irrelevant; this.straightDraw = StraightDrawType.None; Trace.Assert(communityCards.Count > 0, "Cannot classificate an empty list of community cards."); // Create a new list including the board cards and the cards from the hand CardList cards = new CardList(communityCards.Count + 2); foreach (Card c in communityCards) cards.AddCard(c); cards.AddCard(hand.GetFirstCard()); cards.AddCard(hand.GetSecondCard()); // --- Royal flush if (IsRoyalFlush(cards)) { this.hand = HandType.RoyalFlush; this.kicker = KickerType.Irrelevant; return; } // -- Four of a kind if (cards.HaveIdenticalFaces(4)) { this.hand = HandType.FourOfAKind; this.kicker = KickerType.Irrelevant; return; } // -- Full House // If we have three of a kind and two pair at the same time, we have a full house bool isThreeOfAKind = cards.HaveIdenticalFaces(3); bool isTwoPair = IsTwoPair(cards); if (isThreeOfAKind && isTwoPair) { this.hand = HandType.FullHouse; this.kicker = KickerType.Irrelevant; return; } // -- Flush for (int i = 0; i < cards.Count; i++) { int numCardsSameSuit = 0; for (int j = i + 1; j < cards.Count; j++) { if (cards[i].Suit == cards[j].Suit) { numCardsSameSuit++; } } if (numCardsSameSuit >= 4) { this.hand = HandType.Flush; this.kicker = KickerType.Irrelevant; return; } } // -- Straight if (IsStraight(cards)) { this.hand = HandType.Straight; this.kicker = KickerType.Irrelevant; return; } // Calculate draws (if we got until here, there might be some) // Also, no draws are possible at the river if (phase == HoldemGamePhase.River) { draw = DrawType.None; straightDraw = StraightDrawType.None; } else { draw = GetDrawType(cards); if (IsInsideStraightDraw(cards)) { straightDraw = StraightDrawType.InsideStraightDraw; } if (IsOpenEndedStraightDraw(cards)) { straightDraw = StraightDrawType.OpenEndedStraightDraw; } } // -- Trips if (isThreeOfAKind) { this.hand = HandType.ThreeOfAKind; this.kicker = KickerType.Irrelevant; return; } // -- Two pair if (isTwoPair) { this.hand = HandType.TwoPair; this.kicker = KickerType.Irrelevant; return; } // -- Pair Card matching; if (cards.HaveIdenticalFaces(2, out matching)) { // Sort list by face value (ace high first) cards.Sort(SortUsing.AceHigh); // Find kicker (check from end of the list where face values are higher) Card kicker = cards[0]; for (int i = cards.Count - 1; i >= 0; i--) { if (cards[i].Face != matching.Face) { kicker = cards[i]; break; } } this.hand = HandType.Pair; this.kicker = GetKickerTypeFromCard(kicker); this.pair = GetPairType(communityCards, matching, hand.GetFirstCard(), hand.GetSecondCard()); return; } // -- High card cards.Sort(SortUsing.AceHigh); Card highCard = cards.Last; this.hand = HandType.HighCard; this.kicker = GetKickerTypeFromCard(highCard); }
void handHistoryParser_PlayerRaised(string playerName, float raiseAmount, HoldemGamePhase gamePhase) { HoldemPlayer p = (HoldemPlayer)FindPlayer(playerName); if (p == null) { Trace.WriteLine("Raise detected but the player is not in our list. Did he just join?"); return; } if (gamePhase == HoldemGamePhase.Preflop) { /* If somebody already raised, this is a reraise */ if (PlayerRaisedPreflop) { PlayerReRaisedPreflop = true; } /* If this player is the button and he raises while nobody raised or limped before him * this is a good candidate for a steal raise */ if (p.IsButton && !PlayerRaisedPreflop && !PlayerLimpedPreflop && !PlayerCheckedPreflop) { p.IncrementOpportunitiesToStealRaise(); p.IncrementStealRaises(); PlayerStealRaisedPreflop = true; } /* re-raise to a steal raise? */ else if (p.IsSmallBlind && PlayerStealRaisedPreflop) { p.IncrementRaisesToAStealRaise(); SmallBlindReraisedAStealRaise = true; } else if (p.IsBigBlind && PlayerStealRaisedPreflop && !SmallBlindReraisedAStealRaise) { p.IncrementRaisesToAStealRaise(); } /* From the blind raised a raise (but NOT to a reraise) ? */ if (p.IsBlind() && PlayerRaisedPreflop && !PlayerReRaisedPreflop) { p.IncrementRaisesBlindToAPreflopRaise(); } PlayerRaisedPreflop = true; } else if (gamePhase == HoldemGamePhase.Flop) { // Has somebody cbet? if (!PlayerRaisedTheFlop && PlayerCBet) { p.IncrementRaiseToACBet(); } PlayerRaisedTheFlop = true; } p.HasRaised(gamePhase); }
void handHistoryParser_PlayerFolded(string playerName, HoldemGamePhase gamePhase) { HoldemPlayer p = (HoldemPlayer)FindPlayer(playerName); // On some clients, even if the player is sitting out they will make him automatically fold if (p == null) { Trace.WriteLine("Fold detected but the player is not in our list... is he sitting out?"); return; } if (gamePhase == HoldemGamePhase.Preflop) { /* Steal raise opportunity */ if (p.IsButton && !PlayerRaisedPreflop && !PlayerLimpedPreflop && !PlayerCheckedPreflop) { p.IncrementOpportunitiesToStealRaise(); } /* Folded to a steal raise? */ else if (p.IsSmallBlind && PlayerStealRaisedPreflop) { p.IncrementFoldsToAStealRaise(); } else if (p.IsBigBlind && PlayerStealRaisedPreflop && !SmallBlindReraisedAStealRaise) { p.IncrementFoldsToAStealRaise(); } /* Folded to a raise (but NOT to a reraise) ? */ if (p.IsBlind() && PlayerRaisedPreflop && !PlayerReRaisedPreflop) { p.IncrementFoldsBlindToAPreflopRaise(); } } // Has somebody cbet? else if(gamePhase == HoldemGamePhase.Flop && !PlayerRaisedTheFlop && PlayerCBet) { p.IncrementFoldToACBet(); } p.HasFolded(gamePhase); }
/* Will modify the value of currentGamePhase and it might raise a ShowdownWillBegin event */ private bool ParseForGamePhaseChanges(String line) { bool foundMatch = false; Match matchResult; /* Check changes in the game phase */ if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_preflop_phase_token"))) { currentGamePhase = HoldemGamePhase.Preflop; OnHoleCardsWillBeDealt(); } else if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_flop_phase_token"), out matchResult)) { // Detect flop cards String flopCards = matchResult.Groups["flopCards"].Value; List<Card> cards = GenerateCardsFromText(flopCards); // Add them to the board foreach (Card card in cards) boardCards.Add(card); currentGamePhase = HoldemGamePhase.Flop; } else if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_turn_phase_token"), out matchResult)) { // Detect turn card String turnCard = matchResult.Groups["turnCard"].Value; List<Card> cards = GenerateCardsFromText(turnCard); // Add it to the board foreach (Card card in cards) boardCards.Add(card); currentGamePhase = HoldemGamePhase.Turn; } else if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_river_phase_token"), out matchResult)) { // Detect turn card String riverCard = matchResult.Groups["riverCard"].Value; List<Card> cards = GenerateCardsFromText(riverCard); // Add it to the board foreach (Card card in cards) boardCards.Add(card); currentGamePhase = HoldemGamePhase.River; // Call handleFinalBoard this way only if we don't have a more reliable way to find the board if (!pokerClient.HasRegex("hand_history_detect_final_board")) { HandleFinalBoard(boardCards); } } else if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_summary_phase_token"))) { currentGamePhase = HoldemGamePhase.Summary; } else if (pokerClient.HasRegex("hand_history_begin_showdown_phase_token") && (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_showdown_phase_token")))) { // Avoid double event calling if there are multiple showdowns for main/side pots if (currentGamePhase != HoldemGamePhase.Showdown) { // Not all poker clients tell us when (and if) showdown begins, in this case we have it (and found it in the line) currentGamePhase = HoldemGamePhase.Showdown; ShowdownEventRaised = true; OnShowdownWillBegin(); if (pokerClient.GetConfigBoolean("hand_history_begin_showdown_phase_token_matches_hand_winner")) { foundMatch = false; } } } else if (!pokerClient.HasRegex("hand_history_begin_showdown_phase_token")) { // We don't know when showdown really begins. But if somebody showed his hand, it must have begun if (PlayerHasShowedThisRound && !ShowdownEventRaised && currentGamePhase == HoldemGamePhase.River) { currentGamePhase = HoldemGamePhase.Showdown; ShowdownEventRaised = true; Trace.WriteLine("Guessing that showdown will begin"); OnShowdownWillBegin(); } } return foundMatch; }
/* How many times has the player check folded? */ public Statistic GetCheckFoldStats(HoldemGamePhase phase, String category) { return GetCheckActionStats(phase, "Check Fold", category, checkFolds, null); }
/* Helper function to increment the value in one of the hash tables (calls, raises, folds, etc.) */ private void IncrementStatistics(Hashtable table, HoldemGamePhase gamePhase) { if (table != null) table[gamePhase] = (int)table[gamePhase] + 1; }
private void AppendActionsSubstatistics(HoldemGamePhase phase, Statistic statistic, MultipleValueCounter ratings) { float sum = (float)ratings.GetSumOfAllValuesIn(phase); foreach (HoldemHand.Rating rating in Enum.GetValues(typeof(HoldemHand.Rating))) { if (sum == 0) statistic.AddSubStatistic(new StatisticsUnknownData(rating.ToString())); else { float ratio = (float)ratings[phase, rating].Value / sum; statistic.AddSubStatistic(new StatisticsPercentageData(rating.ToString(), ratio)); } } }
private Statistic GetDrawStatistics(HoldemGamePhase phase, String category) { List<StatisticsData> subData = new List<StatisticsData>(10); float sum = (float)draws.GetSumOfAllValuesIn(phase); float max = 0; HoldemPlayerAction mostCommonAction = (HoldemPlayerAction)(-1); for (HoldemPlayerAction action = HoldemPlayerAction.Call; action <= HoldemPlayerAction.CheckFold; action++) { if (sum == 0) subData.Add(new StatisticsUnknownData(action.ToString())); else { float value = draws[phase, action].Value / sum; // Keep track of the max value as to put a quick description on the statistic indicating // which is the most common action taken by the player // Note: in case of equality, the first element is used if (value > max){ max = value; mostCommonAction = action; } subData.Add(new StatisticsPercentageData(action.ToString(), value)); } } String description = "?"; if (mostCommonAction != (HoldemPlayerAction)(-1)) description = "Mostly " + mostCommonAction.ToString().ToLower(); Statistic ret = new Statistic(new StatisticsDescriptiveData("On a straight/flush draw", description), category, subData); return ret; }
/* Pushed all-in */ public void HasPushedAllIn(HoldemGamePhase gamePhase) { pushedAllIn[gamePhase].Increment(); totalAllIns.Increment(); }
/* How many times has the player check called? */ public Statistic GetCheckCallStats(HoldemGamePhase phase, String category) { return GetCheckActionStats(phase, "Check Call", category, checkCalls, checksCallsRatings); }
public List <Statistic> Calculate(HoldemHand hand, HoldemBoard board) { List <Statistic> result = new List <Statistic>(); // What game phase are we in (returns empty list if the board is invalid) HoldemGamePhase phase = HoldemGamePhase.Flop; if (board.Count == 3) { phase = HoldemGamePhase.Flop; } else if (board.Count == 4) { phase = HoldemGamePhase.Turn; } else if (board.Count == 5) { phase = HoldemGamePhase.River; } else { Trace.WriteLine("We were asked to calculate the odds for " + hand.ToString() + " and " + board.ToString() + " but the board seems to be invalid. Returning empty."); return(result); } HoldemHand.ClassificationPostflop classification = (HoldemHand.ClassificationPostflop)hand.GetClassification(phase, board); HoldemHand.ClassificationPostflop.HandType handType = classification.GetHand(); HoldemHand.ClassificationPostflop.DrawType drawType = classification.GetDraw(); HoldemHand.ClassificationPostflop.StraightDrawType straightDrawType = classification.GetStraightDraw(); result.Add(new Statistic(new StatisticsDescriptiveData("Your hand", classification.GetHandDescription()))); if (phase == HoldemGamePhase.Flop || phase == HoldemGamePhase.Turn) { result.Add(new Statistic(new StatisticsDescriptiveData("Draws", classification.GetDrawsDescription()))); if (handType == HoldemHand.ClassificationPostflop.HandType.HighCard) { // Hold high card, hope to make a pair result.Add(CreateOutsStatistic("Improve to a pair", 6, phase)); } else if (handType == HoldemHand.ClassificationPostflop.HandType.Pair) { // Hold a pair, hope to make three of a kind result.Add(CreateOutsStatistic("Improve to three of a kind", 2, phase)); } else if (handType == HoldemHand.ClassificationPostflop.HandType.TwoPair) { // Hold two pair, hope to make a full house result.Add(CreateOutsStatistic("Improve to a full house", 4, phase)); } if (drawType == HoldemHand.ClassificationPostflop.DrawType.Flush) { result.Add(CreateOutsStatistic("Improve to a flush", 9, phase)); } else if (drawType == HoldemHand.ClassificationPostflop.DrawType.Straight) { if (straightDrawType == HoldemHand.ClassificationPostflop.StraightDrawType.OpenEndedStraightDraw) { result.Add(CreateOutsStatistic("Improve to a straight", 8, phase)); } else if (straightDrawType == HoldemHand.ClassificationPostflop.StraightDrawType.InsideStraightDraw) { result.Add(CreateOutsStatistic("Improve to a straight", 4, phase)); } else { Trace.WriteLine("Warning! Straight draw detected when calculating odds but none of the cases was matched?"); } } else if (drawType == HoldemHand.ClassificationPostflop.DrawType.FlushAndStraight) { // Open ended straight flush draw if (straightDrawType == HoldemHand.ClassificationPostflop.StraightDrawType.OpenEndedStraightDraw) { // 9 outs for the flush + 6 outs (2 outs for the straight draw are the suit we need to make the flush) result.Add(CreateOutsStatistic("Improve to a flush or straight", 15, phase)); } else if (straightDrawType == HoldemHand.ClassificationPostflop.StraightDrawType.InsideStraightDraw) { // inside straight flushd draw, 9 outs + 3 (1 out is the suit we need) result.Add(CreateOutsStatistic("Improve to a flush or straight", 12, phase)); } else { Trace.WriteLine("Warning! Flush and straight draw detected when calculating odds but none of the cases was matched?"); } } } return(result); }
/* How many times has the player check raised? */ public Statistic GetCheckRaiseStats(HoldemGamePhase phase, String category) { return GetCheckActionStats(phase, "Check Raise", category, checkRaises, checksRaisesRatings); }
protected void OnPlayerCalled(String playerName, float amount, HoldemGamePhase gamePhase) { if (PlayerCalled != null) PlayerCalled(playerName, amount, gamePhase); }
/* How many times has the player raised? */ public Statistic GetRaiseStats(HoldemGamePhase phase, String category) { if (sawStreet[phase].Value == 0) return CreateUnknownActionStatistic("Raises", category); else { float raiseRatio = (float)raises[phase].Value / (float)sawStreet[phase].Value; Statistic ret = new Statistic(new StatisticsPercentageData("Raises", raiseRatio), category); AppendActionsSubstatistics(phase, ret, raisesRatings); return ret; } }
protected void OnPlayerFolded(String playerName, HoldemGamePhase gamePhase) { if (PlayerFolded != null) PlayerFolded(playerName, gamePhase); }
/* Folded */ public void HasFolded(HoldemGamePhase gamePhase) { /* We're only interested in the first action */ if (!sawStreet[gamePhase].WasIncremented) { folds[gamePhase].Increment(); } // Check fold? if (checks[gamePhase].WasIncremented) { checkFolds[gamePhase].Increment(); } IncrementStatistics(totalFolds, gamePhase); sawStreet[gamePhase].Increment(); }
/* Calculates the type of the hand given a board * during a game phase */ public HoldemHand.Classification GetClassification(HoldemGamePhase phase, HoldemBoard board) { if (phase == HoldemGamePhase.Preflop) { return new ClassificationPreflop(this); } else { return new ClassificationPostflop(this, phase, board); } }
/* This player has raised, increment the stats */ public void HasRaised(HoldemGamePhase gamePhase) { /* We're only interested in the first action */ if (!sawStreet[gamePhase].WasIncremented) { raises[gamePhase].Increment(); } if (gamePhase == HoldemGamePhase.Preflop) { voluntaryPutMoneyPreflop.Increment(); } // Check raise? if (checks[gamePhase].WasIncremented) { checkRaises[gamePhase].Increment(); } IncrementStatistics(totalRaises, gamePhase); sawStreet[gamePhase].Increment(); }
/* Will modify the value of currentGamePhase * and it might raise a ShowdownWillBegin event */ private bool ParseForGamePhaseChanges(String line) { bool foundMatch = false; Match matchResult; /* Check changes in the game phase */ if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_preflop_phase_token"))) { currentGamePhase = HoldemGamePhase.Preflop; OnHoleCardsWillBeDealt(); } else if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_flop_phase_token"), out matchResult)) { // Detect flop cards String flopCards = matchResult.Groups["flopCards"].Value; List <Card> cards = GenerateCardsFromText(flopCards); // Add them to the board foreach (Card card in cards) { boardCards.Add(card); } currentGamePhase = HoldemGamePhase.Flop; } else if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_turn_phase_token"), out matchResult)) { // Detect turn card String turnCard = matchResult.Groups["turnCard"].Value; List <Card> cards = GenerateCardsFromText(turnCard); // Add it to the board foreach (Card card in cards) { boardCards.Add(card); } currentGamePhase = HoldemGamePhase.Turn; } else if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_river_phase_token"), out matchResult)) { // Detect turn card String riverCard = matchResult.Groups["riverCard"].Value; List <Card> cards = GenerateCardsFromText(riverCard); // Add it to the board foreach (Card card in cards) { boardCards.Add(card); } currentGamePhase = HoldemGamePhase.River; // Call handleFinalBoard this way only if we don't have a more reliable way to find the board if (!pokerClient.HasRegex("hand_history_detect_final_board")) { HandleFinalBoard(boardCards); } } else if (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_summary_phase_token"))) { currentGamePhase = HoldemGamePhase.Summary; } else if (pokerClient.HasRegex("hand_history_begin_showdown_phase_token") && (foundMatch = LineMatchesRegex(line, pokerClient.GetRegex("hand_history_begin_showdown_phase_token")))) { // Avoid double event calling if there are multiple showdowns for main/side pots if (currentGamePhase != HoldemGamePhase.Showdown) { // Not all poker clients tell us when (and if) showdown begins, in this case we have it (and found it in the line) currentGamePhase = HoldemGamePhase.Showdown; ShowdownEventRaised = true; OnShowdownWillBegin(); if (pokerClient.GetConfigBoolean("hand_history_begin_showdown_phase_token_matches_hand_winner")) { foundMatch = false; } } } else if (!pokerClient.HasRegex("hand_history_begin_showdown_phase_token")) { // We don't know when showdown really begins. But if somebody showed his hand, it must have begun if (PlayerHasShowedThisRound && !ShowdownEventRaised && currentGamePhase == HoldemGamePhase.River) { currentGamePhase = HoldemGamePhase.Showdown; ShowdownEventRaised = true; Trace.WriteLine("Guessing that showdown will begin"); OnShowdownWillBegin(); } } return(foundMatch); }