/// <summary> /// Loads saved all pairs pre flop equities. /// </summary> public static void Load() { _data = new float[N_HOLECARDS_DOUBLE][]; for (int i = 0; i < N_HOLECARDS_DOUBLE; i++) { _data[i] = new float[N_HOLECARDS_DOUBLE]; for (int j = 0; j < N_HOLECARDS_DOUBLE; j++) { _data[i][j] = 0; } } using (var file = new StreamReader(File.OpenRead(fileName))) { while (!file.EndOfStream) { string line = file.ReadLine(); HoleCards hand1 = new HoleCards(line.Substring(0, 4)); HoleCards hand2 = new HoleCards(line.Substring(5, 4)); float eq = float.Parse(line.Substring(10), CultureInfo.InvariantCulture); _data[hand1.ToInt()][hand2.ToInt()] = eq; } } }
/// <summary> /// Calculates Pre-Flop-Equity of particular hole cards against particular hole cards of the villian. /// </summary> public static float Calculate(HoleCards heroHoleCards, HoleCards villanHoleCards) { int[] aheadGlobal = new int[52]; int[] tieGlobal = new int[52]; int[] behindGlobal = new int[52]; for (int i = 0; i < 52; i++) { aheadGlobal[i] = 0; tieGlobal[i] = 0; behindGlobal[i] = 0; } //for (int i0 = 0; i0 < 48; i0++) // Flop 1 Parallel.For(0, 48, (i0) => { CalculateTmp(aheadGlobal, tieGlobal, behindGlobal, heroHoleCards, villanHoleCards, i0); }); int aheadSum = 0; int tieSum = 0; int behindSum = 0; for (int i = 0; i < 52; i++) { aheadSum += aheadGlobal[i]; tieSum += tieGlobal[i]; behindSum += behindGlobal[i]; } float total = aheadSum + tieSum + behindSum; return((aheadSum + tieSum / 2.0f) / total); }
private static int AddToData(System.IO.StreamWriter file, HoleCards hand1, HoleCards hand2, float equity) { int total = 0; for (Card.Suite s11 = Card.Suite.Clubs; s11 <= Card.Suite.Spades; s11++) { for (Card.Suite s12 = Card.Suite.Clubs; s12 <= Card.Suite.Spades; s12++) { if (!DoSuitsAgree(hand1.Card1.suite, hand1.Card0.suite, s12, s11)) { continue; } for (Card.Suite s21 = Card.Suite.Clubs; s21 <= Card.Suite.Spades; s21++) { if (!DoSuitsAgree(hand2.Card0.suite, hand1.Card0.suite, s21, s11)) { continue; } if (!DoSuitsAgree(hand2.Card0.suite, hand1.Card1.suite, s21, s12)) { continue; } for (Card.Suite s22 = Card.Suite.Clubs; s22 <= Card.Suite.Spades; s22++) { if (!DoSuitsAgree(hand2.Card1.suite, hand1.Card0.suite, s22, s11)) { continue; } if (!DoSuitsAgree(hand2.Card1.suite, hand1.Card1.suite, s22, s12)) { continue; } if (!DoSuitsAgree(hand2.Card1.suite, hand2.Card0.suite, s22, s21)) { continue; } HoleCards hand1_new = new HoleCards(hand1.Card0.rank, s11, hand1.Card1.rank, s12); HoleCards hand2_new = new HoleCards(hand2.Card0.rank, s21, hand2.Card1.rank, s22); total += AddToDataTmp(file, hand1_new, hand2_new, equity); total += AddToDataTmp(file, hand2_new, hand1_new, 1.0f - equity); } } } } return(total); }
public float getHoleCardsProb(HoleCards holeCards) { for (var i = 0; i < N_HOLECARDS; i++) { if (Data[i].Ind == holeCards.ToInt()) { return(Data[i].Equity); } } return(0.0f); }
public Hand() { Client = PokerClient.G5; BigBlindSize = 4; HeroName = ""; PlayersNames = new List <string>(); HeroHoleCards = null; ActionList = new List <Action>(); Board = new Board(); PlayerBalanceChanges = new List <int>(); PlayerStacks = new List <int>(); }
private static int AddToDataTmp(System.IO.StreamWriter file, HoleCards hand1, HoleCards hand2, float equity) { int total = 0; if (!(_data[hand1.ToInt()][hand2.ToInt()] > 0)) { _data[hand1.ToInt()][hand2.ToInt()] = equity; file.WriteLine(hand1.ToString() + ":" + hand2.ToString() + "=" + (equity * 100).ToString("f2")); total++; } return(total); }
public void dealHoleCards(Card card0, Card card1) { Debug.Assert(_street == Street.PreFlop); _heroHoleCards = new HoleCards(card0, card1); _currentHand.setHoleCardsHoldem(card0, card1); for (int i = 0; i < _players.Count; i++) { if (i != _heroInd) { _players[i].BanCardInRange(card0, false); _players[i].BanCardInRange(card1, false); } } }
public BotGameState(string[] playerNames, int heroIndex, int buttonInd, int bigBlingSize, int startStackSize, PokerClient client, TableType tableType, Estimators.IActionEstimator actionEstimator) { _actionEstimator = actionEstimator; _tableType = tableType; _players = new List <Player>(); _board = new Board(); _heroHoleCards = new HoleCards(0); _bigBlingSize = bigBlingSize; _pokerClient = client; _heroInd = heroIndex; _buttonInd = buttonInd; foreach (string playerName in playerNames) { _players.Add(new Player(playerName, startStackSize, null)); } }
/// <summary> /// Board and hand are expected to be sorted /// </summary> private static int GetFlushRank(HoleCards heroHoleCards, Card[] sortedBoard, Card.Suite suite) { Card[] allCards = new Card[7]; InsertSortedHoleCardsToSortedBoard(allCards, heroHoleCards, sortedBoard); int sum = 0; int weight = 15 * 15 * 15 * 15; for (int n = 5, k = 0; n > 0; k++) { if (allCards[k].suite == suite) { sum += weight * (int)allCards[k].rank; weight /= 15; n--; } } return(sum); }
private static int TotalCombinations() { int total = 0; for (int i = 0; i < N_HOLECARDS_DOUBLE; i++) { for (int j = 0; j < N_HOLECARDS_DOUBLE; j++) { HoleCards hand1 = new HoleCards(i); HoleCards hand2 = new HoleCards(j); // Hand1 not valid if (hand1.Card0.ToInt() >= hand1.Card1.ToInt()) { continue; } // Hand2 not valid if (hand2.Card0.ToInt() >= hand2.Card1.ToInt()) { continue; } // At least one card in each hand is the same => not valid if (hand1.Card0.ToInt() == hand2.Card0.ToInt() || hand1.Card0.ToInt() == hand2.Card1.ToInt() || hand1.Card1.ToInt() == hand2.Card0.ToInt() || hand1.Card1.ToInt() == hand2.Card1.ToInt()) { continue; } total++; } } return(total); }
private static void InsertSortedHoleCardsToSortedBoard(Card[] allCards, HoleCards heroHoleCards, Card[] board) { int boardI = 0; int handI = 0; int k = 0; while (k < 7) { Card heroCard = heroHoleCards.GetCard(handI); if (boardI < 5 && handI < 2) { if (board[boardI].rank > heroCard.rank) { allCards[k] = board[boardI]; boardI++; } else { allCards[k] = heroCard; handI++; } } else if (boardI < 5) { allCards[k] = board[boardI]; boardI++; } else { allCards[k] = heroCard; handI++; } k++; } }
public static void Holdem_EstimateEV(out float checkCallEV, out float betRaiseEV, int buttonInd, int heroIndex, HoleCards heroHoleCards, List <Player> playerList, Board board, Street street, int numBets, int numCallers, int bigBlindSize, DecisionMakingContext dmContext) { Unmanaged_HoleCards uHoleCards = new Unmanaged_HoleCards(heroHoleCards); Unmanaged_Player[] players = new Unmanaged_Player[playerList.Count]; for (int i = 0; i < playerList.Count; i++) { players[i] = new Unmanaged_Player(playerList[i], i); } Unmanaged_Card[] cards = BoardToUnmanaged(board); checkCallEV = 0.0f; betRaiseEV = 0.0f; EstimateEV(ref checkCallEV, ref betRaiseEV, buttonInd, heroIndex, ref uHoleCards, players, playerList.Count, cards, (int)street, numBets, numCallers, bigBlindSize, dmContext.GC); }
public void dealHoleCards(HoleCards holeCards) { dealHoleCards(holeCards.Card0, holeCards.Card1); }
private int GetHandStrength(HoleCards holeCards, Card[] sortedBoard) { int strength = 0; int base0 = 1; int base1 = 15; int base2 = base1 * 15; int base3 = base2 * 15; int base4 = base3 * 15; int base5 = base4 * 15; bool sFlushFound = false; // Check for straight flush if (flush >= 0) { if (HasStreight()) { int tmpStrength = HandStrength.calculateHandStrength(holeCards, sortedBoard).Value(); if (tmpStrength >= ((int)HandRank.SFlush) * base5) { sFlushFound = true; strength = tmpStrength; } } } if (!sFlushFound) { if (poker != 0) { strength = ((int)HandRank.Poker) * base5 + GetPokerRank() * base4 + GetPokerKicker() * base2; } else if ((nTrips >= 1 && nPairs >= 1) || (nTrips >= 2)) { strength = ((int)HandRank.FullHouse) * base5 + GetFullRank() * base3; } else if (flush >= 0) { int flushRank = GetFlushRank(holeCards, sortedBoard, (Card.Suite)flush); strength = ((int)HandRank.Flush) * base5 + flushRank * base0; } else if (HasStreight()) { strength = ((int)HandRank.Straight) * base5 + GetStreightRank() * base4; } else if (nTrips >= 1) { strength = ((int)HandRank.Trips) * base5 + GetTripsRank() * base4 + GetTripsKicker() * base2; } else if (nPairs >= 2) { strength = ((int)HandRank.TwoPair) * base5 + GetTwoPairRank() * base3 + GetTwoPairKicker() * base2; } else if (nPairs == 1) { int pairRank = GetPairRank(); strength = ((int)HandRank.OnePair) * base5 + pairRank * base4 + GetOnePairKicker(pairRank) * base0; } else { strength = ((int)HandRank.HighCard) * base5 + GetHighCardKicker() * base0; } } return(strength); }
private static void CalculateTmp(int[] aheadGlobal, int[] tieGlobal, int[] behindGlobal, HoleCards heroHoleCards, HoleCards villanHoleCards, int i0) { bool[] knownCard = new bool[52]; Card[] deck = new Card[52]; for (int i = 0; i < 52; i++) { knownCard[i] = false; deck[i] = new Card(i); } knownCard[heroHoleCards.Card0.ToInt()] = true; knownCard[heroHoleCards.Card1.ToInt()] = true; knownCard[villanHoleCards.Card0.ToInt()] = true; knownCard[villanHoleCards.Card1.ToInt()] = true; int ahead = 0; int tie = 0; int behind = 0; HandStrengthCounter heroCounter = new HandStrengthCounter(); HandStrengthCounter villanCounter = new HandStrengthCounter(); heroCounter.AddCard(heroHoleCards.Card0); heroCounter.AddCard(heroHoleCards.Card1); villanCounter.AddCard(villanHoleCards.Card0); villanCounter.AddCard(villanHoleCards.Card1); Card[] board = new Card[5]; if (!knownCard[i0]) { board[0] = deck[i0]; heroCounter.AddCard(deck[i0]); villanCounter.AddCard(deck[i0]); for (int i1 = i0 + 1; i1 < 49; i1++) // Flop 2 { if (knownCard[i1]) { continue; } board[1] = deck[i1]; heroCounter.AddCard(deck[i1]); villanCounter.AddCard(deck[i1]); for (int i2 = i1 + 1; i2 < 50; i2++) // Flop 3 { if (knownCard[i2]) { continue; } board[2] = deck[i2]; heroCounter.AddCard(deck[i2]); villanCounter.AddCard(deck[i2]); for (int i3 = i2 + 1; i3 < 51; i3++) // Turn { if (knownCard[i3]) { continue; } board[3] = deck[i3]; heroCounter.AddCard(deck[i3]); villanCounter.AddCard(deck[i3]); for (int i4 = i3 + 1; i4 < 52; i4++) // River { if (knownCard[i4]) { continue; } board[4] = deck[i4]; heroCounter.AddCard(deck[i4]); villanCounter.AddCard(deck[i4]); int result = heroCounter.CompareHandStrength(heroHoleCards, villanHoleCards, villanCounter, board); if (result == HandStrengthCounter.AHEAD) { ahead++; } else if (result == HandStrengthCounter.BEHIND) { behind++; } else if (result == HandStrengthCounter.TIE) { tie++; } heroCounter.RemoveCard(deck[i4]); villanCounter.RemoveCard(deck[i4]); } heroCounter.RemoveCard(deck[i3]); villanCounter.RemoveCard(deck[i3]); } heroCounter.RemoveCard(deck[i2]); villanCounter.RemoveCard(deck[i2]); } heroCounter.RemoveCard(deck[i1]); villanCounter.RemoveCard(deck[i1]); } heroCounter.RemoveCard(deck[i0]); villanCounter.RemoveCard(deck[i0]); } aheadGlobal[i0] = ahead; tieGlobal[i0] = tie; behindGlobal[i0] = behind; }
/// <summary> /// Returns AHEAD if ahead, TIE tie, -1 BEHIND. /// </summary> public int CompareHandStrength(HoleCards heroHoleCards, HoleCards villainHoleCards, HandStrengthCounter villainCounter, Card[] sortedBoard) { HandRank heroRank = this.GetHandRank(); HandRank villanRank = villainCounter.GetHandRank(); bool possibleStraightFlushConflict = false; bool resolved = false; int result = 0; if ((heroRank >= HandRank.Flush && villanRank >= HandRank.Flush)) { if ((this.HasFlush() && this.HasStreight()) || (villainCounter.HasFlush() && villainCounter.HasStreight())) { possibleStraightFlushConflict = true; } } if (possibleStraightFlushConflict) { resolved = false; } else if (heroRank > villanRank) { result = AHEAD; resolved = true; } else if (heroRank < villanRank) { result = BEHIND; resolved = true; } else if (heroRank == HandRank.HighCard) { int heroTmp = this.GetHighCardKicker(); int villanTmp = villainCounter.GetHighCardKicker(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { result = TIE; resolved = true; } } else if (heroRank == HandRank.OnePair) { int heroTmp = this.GetPairRank(); int villanTmp = villainCounter.GetPairRank(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { heroTmp = this.GetOnePairKicker(heroTmp); villanTmp = villainCounter.GetOnePairKicker(villanTmp); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { result = TIE; resolved = true; } } } else if (heroRank == HandRank.TwoPair) { int heroTmp = this.GetTwoPairRank(); int villanTmp = villainCounter.GetTwoPairRank(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { heroTmp = this.GetTwoPairKicker(); villanTmp = villainCounter.GetTwoPairKicker(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { result = TIE; resolved = true; } } } else if (heroRank == HandRank.Trips) { int heroTmp = this.GetTripsRank(); int villanTmp = villainCounter.GetTripsRank(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { heroTmp = this.GetTripsKicker(); villanTmp = villainCounter.GetTripsKicker(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { result = TIE; resolved = true; } } } else if (heroRank == HandRank.Straight) { int heroTmp = this.GetStreightRank(); int villanTmp = villainCounter.GetStreightRank(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { result = TIE; resolved = true; } } else if (heroRank == HandRank.Flush) { int heroTmp = GetFlushRank(heroHoleCards, sortedBoard, this.GetFlushSuite()); int villanTmp = GetFlushRank(villainHoleCards, sortedBoard, villainCounter.GetFlushSuite()); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { result = TIE; resolved = true; } } else if (heroRank == HandRank.FullHouse) { int heroTmp = this.GetFullRank(); int villanTmp = villainCounter.GetFullRank(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { result = TIE; resolved = true; } } else if (heroRank == HandRank.Poker) { int heroTmp = this.GetPokerRank(); int villanTmp = villainCounter.GetPokerRank(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { heroTmp = this.GetPokerKicker(); villanTmp = villainCounter.GetPokerKicker(); if (heroTmp > villanTmp) { result = AHEAD; resolved = true; } else if (heroTmp < villanTmp) { result = BEHIND; resolved = true; } else { result = TIE; resolved = true; } } } if (!resolved) { villainCounter.GetHandStrength(villainHoleCards, sortedBoard); int villanStrength = villainCounter.GetHandStrength(villainHoleCards, sortedBoard); int heroStrength = this.GetHandStrength(heroHoleCards, sortedBoard); if (heroStrength > villanStrength) { result = AHEAD; } else if (heroStrength < villanStrength) { result = BEHIND; } else { result = TIE; } } return(result); }
public void setHoleCardsHoldem(Card card0, Card card1) { HeroHoleCards = new HoleCards(card0, card1); }
public static HandStrength calculateHandStrength(HoleCards heroHoleCards, Board board) { return(calculateHandStrength(heroHoleCards, board.getSortedCards())); }
/// <summary> /// Calculates PFR for all hole cards against all other hole cards. /// Last couple hours. Saved to file afterwards. /// </summary> /// <param name="backgroundWorker">For reporting progress</param> public static void AllPairsPreFlopEquity(IProgressReporter progressReporter) { int total = TotalCombinations(); int done = 0; for (int i = 0; i < N_HOLECARDS_DOUBLE; i++) { for (int j = 0; j < N_HOLECARDS_DOUBLE; j++) { if (_data[i][j] > 0) { done++; } } } if (progressReporter != null) { progressReporter.ReportProgress((100 * done) / total, new ProgressReport(total, done, 0)); } for (int i = 0; i < 51; i++) { if (progressReporter != null && progressReporter.isCancellationPending()) { break; } for (int j = i + 1; j < 52; j++) { if (progressReporter != null && progressReporter.isCancellationPending()) { break; } // i < j HoleCards heroHand = new HoleCards(i, j); for (int k = 0; k < 51; k++) { if (progressReporter != null && progressReporter.isCancellationPending()) { break; } if (k == i || k == j) { continue; } float[] tmpEquity = new float[52]; for (int ppp = 0; ppp < 52; ppp++) { tmpEquity[ppp] = 0; } DateTime startTime = DateTime.Now; int previousDone = done; //for (int l = k + 1; l < 52; l++ ) Parallel.For(k + 1, 52, (l) => { if (l != i && l != j) { // k < l HoleCards villanHand = new HoleCards(k, l); if (_data[heroHand.ToInt()][villanHand.ToInt()] == 0) { tmpEquity[l] = Calculate(heroHand, villanHand); } } }); using (var file = File.AppendText(fileName)) { for (int l = k + 1; l < 52; l++) { if (tmpEquity[l] > 0) { HoleCards villanHand = new HoleCards(k, l); done += AddToData(file, heroHand, villanHand, tmpEquity[l]); } } } DateTime endTime = DateTime.Now; TimeSpan dTime = endTime - startTime; float msPerComb = (done > previousDone) ? (float)(dTime.TotalMilliseconds / (done - previousDone)) : 0; if (progressReporter != null) { progressReporter.ReportProgress((100 * done) / total, new ProgressReport(total, done, msPerComb)); } } } } }
public static void GameContext_NewFlop(DecisionMakingContext dmContext, Board board, HoleCards heroHoleCards) { GameContext_NewFlop(dmContext.GC, board.Flop[0].ToString(), board.Flop[1].ToString(), board.Flop[2].ToString(), (heroHoleCards != null) ? heroHoleCards.ToString() : null); }
/// <summary> /// Board and hand are expected to be sorted. /// </summary> public static HandStrength calculateHandStrength(HoleCards heroHoleCards, Card[] sortedBoard) { Card[] allCards = new Card[7]; Card[] possibleHand = new Card[5]; InsertSortedHoleCardsToSortedBoard(allCards, heroHoleCards, sortedBoard); HandStrength hsCandidate = new HandStrength(); HandStrength maxHandStrangth = null; int maxHandStrangthValue = 0; for (int i = 0; i < 6; i++) { for (int j = i + 1; j < 7; j++) { int k = 0; if (i != 0 && j != 0) { possibleHand[k++] = allCards[0]; } if (i != 1 && j != 1) { possibleHand[k++] = allCards[1]; } if (i != 2 && j != 2) { possibleHand[k++] = allCards[2]; } if (i != 3 && j != 3) { possibleHand[k++] = allCards[3]; } if (i != 4 && j != 4) { possibleHand[k++] = allCards[4]; } if (i != 5 && j != 5) { possibleHand[k++] = allCards[5]; } if (i != 6 && j != 6) { possibleHand[k++] = allCards[6]; } HandStrength.calculateHandStrengthSorted(ref hsCandidate, possibleHand); int value = hsCandidate.Value(); if (maxHandStrangthValue < value) { maxHandStrangthValue = value; maxHandStrangth = new HandStrength(hsCandidate); } } } return(maxHandStrangth); }
public Unmanaged_HoleCards(HoleCards holeCards) { Card0 = new Unmanaged_Card(holeCards.Card0); Card1 = new Unmanaged_Card(holeCards.Card1); }