public Dictionary <Hand, int> ComputeOuts(Hand h, List <Card> holecards, List <Card> community, out Dictionary <Hand, List <Card> > whichouts) { Deck d = new Deck(); HandEvaluator he = new HandEvaluator(); Dictionary <Hand, int> handOuts = new Dictionary <Hand, int>(); Dictionary <Hand, List <Card> > handWhichOuts = new Dictionary <Hand, List <Card> >(); Dictionary <Hand, double> handRanks = new Dictionary <Hand, double>(); Dictionary <Hand, double> handWithoutCard = new Dictionary <Hand, double>(); // C# WHAT? This codes no works //List<string> testing = new List<string>(); //testing.Add("t"); //testing.Add("a"); //Console.WriteLine("{0}", testing); //testing.Remove("t"); //Console.WriteLine("{0}", testing); //return handOuts; // END This codes no works // initialize dict and remove visible cards to everyone. Outs are only computed on cards we can't see. handOuts.Add(h, 0); handWhichOuts.Add(h, new List <Card>()); d.RemoveCards(community); d.RemoveCards(holecards); // for every card left in the deck not visible, see which cards unilaterally improve hands positions relative to eachother // the card that produces a move to the best hand gets counted for that hand. foreach (Card c in d.DECK) { string handRank; double boardRankwith = 0.0; double boardRankwithout = 0.0; // Rank with card h.AddCard(c); //Console.WriteLine("NumCardsToRank: {0}\nMaxHandSize: {1}", h.NumCardsToRank, h.MaxHandSize); he = new HandEvaluator(); handRanks[h] = he.RankHand(h, out handRank); // Rank without card h.RemoveCard(c); he = new HandEvaluator(); handWithoutCard[h] = he.RankHand(h, out handRank); // Rank Board Cards if (community.Count > 0) { // board rank without card he = new HandEvaluator(); boardRankwithout = he.RankHand(new Hand(community, 7, 5), out handRank); // board rank with card he = new HandEvaluator(); community.Add(c); boardRankwith = he.RankHand(new Hand(community, 7, 5), out handRank); community.Remove(c); // Any card that increases your position one level and your position is at least 2 hand levels better than the board with the card. // we do two levels because if the board pairs and is a favorable pair to your hole cards, you hand will increase 2x. 2-pair -> board pairs -> full house. // all other cases should be handled by the if statement below. if ((Math.Round(handRanks[h], 2) > Math.Round(handWithoutCard[h], 2)) && (Math.Abs((int)handRanks[h] - (int)boardRankwith)) >= 2) { //Console.WriteLine("Card: {0}\nHoleCards: {1}\nCommunity: {2}\nHandRankWith: {3}\nHandRankWithout: {4}\nBoardRankWith: {5}\nBoardRankWithout: {6}", c.CardToString(), new Hand(holecards, 7,5).HandToString(), new Hand(community, 7 ,5).HandToString(), handRanks[h], handWithoutCard[h], boardRankwith, boardRankwithout); handOuts[h]++; handWhichOuts[h].Add(c); //Console.ReadLine(); } // The above if block does not catch all cases. If you have the same rank as the board but a higher pair, three kind, etc.. these are still favorable outs. // Example: Holecards: Ac2s Board: As5d5c // Board has a pair and you have a pair, but your pair is better. if (Math.Round(handRanks[h], 2) > Math.Round(boardRankwith, 2) && (Math.Round(handRanks[h], 2) > Math.Round(handWithoutCard[h], 2)) && (int)handRanks[h] == (int)boardRankwith && ((int)handRanks[h] == 4 || (int)handRanks[h] == 5 || (int)handRanks[h] == 8)) { // your hand is better than boards. You hand with the card is better than your previous hand. you have the same hand as the board. and the hand is a straight, flush, or straight flush. //Console.WriteLine("Card: {0}\nHoleCards: {1}\nCommunity: {2}\nHandRankWith: {3}\nHandRankWithout: {4}\nBoardRankWith: {5}\nBoardRankWithout: {6}", c.CardToString(), new Hand(holecards, 7, 5).HandToString(), new Hand(community, 7, 5).HandToString(), handRanks[h], handWithoutCard[h], boardRankwith, boardRankwithout); handOuts[h]++; handWhichOuts[h].Add(c); //Console.ReadLine(); } } //// who ever is the winner after this card is delt gets that out. //// this is more for people watching the play-by-play rather than analysis. Players only know what cards they can see. //foreach (KeyValuePair<Hand, double> kv in handRanksSort) //{ // handCurrentPosition[kv.Key] = handRanksSort.IndexOf(kv); // // keep a list of the number of outs and the actual cards which are considered outs for that hand. // handOuts[handRanksSort[0].Key]++; // handWhichOuts[handRanksSort[0].Key].Add(c); //} } whichouts = handWhichOuts; return(handOuts); }
static void Main(string[] args) { // takes a full path to a directory that contains raw *.txt poker history files from 888 poker. IHandHistoryParserFactory handHistoryParserFactory = new HandHistoryParserFactoryImpl(); // Get the correct parser from the factory. var handHistoryParser = new Poker888FastParserImpl(); HandHistoryParserFastImpl fastParser = handHistoryParser as HandHistoryParserFastImpl; try { // The true causes hand-parse errors to get thrown. If this is false, hand-errors will // be silent and null will be returned. string[] files = Directory.GetFiles(args[0], "*.txt", SearchOption.AllDirectories); int fileCount = files.Length; foreach (string file in files) { Console.WriteLine("number of files left {0} out of {1}", fileCount--, files.Length); string fileText = new StreamReader(file).ReadToEnd(); var hands = fastParser.SplitUpMultipleHandsToLines(fileText); var outputFile = new StreamWriter(file + ".csv"); outputFile.WriteLine("DateOfHandUtc,HandId,DealerButtonPosition,TableName,GameDescription,NumPlayersActive,NumPlayersSeated,Rake,ComumnityCards,TotalPot,PlayerName,HoleCards,StartingStack,SeatNumber,ActionNumber,Amount,HandActionType,Outs,CardOuts,CurrentHandRank,currentPostSize,Street,IsAggressiveAction,IsAllIn,IsAllInAction,IsBlinds,IsGameAction,IsPreFlopRaise,IsRaise,IsWinningsAction"); foreach (var hand in hands) { var parsedHand = fastParser.ParseFullHandHistory(hand, true); // probably not the best way to do this. This should be added to the ParseHandActions function or something. decimal currentPotSize = 0; int actionNumber = 0; foreach (var action in parsedHand.HandActions) { // I tried to do this (this = 'actionNumber++') rtdfgcvdrt properly via the ParseHandActions function in Poker888FastParserImpl.cs file to be 1-1 with the raw handlines, however // I was getting some un-expected behavior when the action was all in and the winning action the handline index would be 0 so you would end up with // actions sequences like 1,2,3,4,5,6,0,8,9,10. actionNumber++; if (action.HandActionType == HandHistories.Objects.Actions.HandActionType.ANTE || action.HandActionType == HandHistories.Objects.Actions.HandActionType.BET || action.HandActionType == HandHistories.Objects.Actions.HandActionType.SMALL_BLIND || action.HandActionType == HandHistories.Objects.Actions.HandActionType.RAISE || action.HandActionType == HandHistories.Objects.Actions.HandActionType.BIG_BLIND || action.HandActionType == HandHistories.Objects.Actions.HandActionType.CALL || action.HandActionType == HandHistories.Objects.Actions.HandActionType.ALL_IN) { currentPotSize += action.Amount; } // Don't judge me.... this code is just chaos...but it's works. string handRank; HandEvaluator.HandEvaluator he = new HandEvaluator.HandEvaluator(); string handstring = String.Format("{0}{1}", parsedHand.Players.First(p => p.PlayerName.Equals(action.PlayerName)).HoleCards, parsedHand.ComumnityCards); string flopstring; string turnstring; string riverstring; string currenthandstring; Hand h = new Hand(); // holecards Hand hc = new Hand(); Dictionary<Hand, int> handOuts = new Dictionary<Hand, int>(); Dictionary<Hand, List<Card>> cardouts; int outs = 0; double hr = 0.0; string couts = ""; if (handstring.Length >= 14) { currenthandstring = ""; flopstring = handstring.Substring(4, 6); turnstring = handstring.Substring(10, 2); riverstring = handstring.Substring(12, 2); // build the hand play-by-play so we can get current hand ranking and also build in hand outs. switch (action.Street) { case HandHistories.Objects.Cards.Street.Flop: currenthandstring = handstring.Substring(0, 4) + flopstring; h = new Hand(currenthandstring, 7, 5); hc = new Hand(handstring.Substring(0, 4), 7, 5); hr = he.RankHand(h, out handRank); handOuts = he.ComputeOuts(h, hc.HAND, new Hand(flopstring, 7, 5).HAND, out cardouts); outs = handOuts[h]; couts = new Hand(cardouts[h], 52, 5).HandToString(); break; case HandHistories.Objects.Cards.Street.Turn: currenthandstring = handstring.Substring(0, 4) + flopstring + turnstring; h = new Hand(currenthandstring, 7, 5); hc = new Hand(handstring.Substring(0, 4), 7, 5); hr = he.RankHand(h, out handRank); handOuts = he.ComputeOuts(h, hc.HAND, new Hand(flopstring + turnstring, 7, 5).HAND, out cardouts); outs = handOuts[h]; couts = new Hand(cardouts[h], 52, 5).HandToString(); break; case HandHistories.Objects.Cards.Street.River: currenthandstring = handstring.Substring(0, 4) + flopstring + turnstring + riverstring; h = new Hand(currenthandstring, 7, currenthandstring.Length / 2); hc = new Hand(handstring.Substring(0, 4), 7, 5); hr = he.RankHand(h, out handRank); outs = 0; // No need to compute outs on the river. No more cards to come. break; default: hr = 0.0; outs = 0; break; } } else { hr = 0.0; outs = 0; } outputFile.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21},{22},{23},{24},{25},{26},{27},{28},{29}", parsedHand.DateOfHandUtc , parsedHand.HandId , parsedHand.DealerButtonPosition , parsedHand.TableName , parsedHand.GameDescription , parsedHand.NumPlayersActive , parsedHand.NumPlayersSeated , parsedHand.Rake , parsedHand.ComumnityCards , parsedHand.TotalPot , action.PlayerName , parsedHand.Players.First(p => p.PlayerName.Equals(action.PlayerName)).HoleCards , parsedHand.Players.First(p => p.PlayerName.Equals(action.PlayerName)).StartingStack , parsedHand.Players.First(p => p.PlayerName.Equals(action.PlayerName)).SeatNumber , actionNumber , action.Amount , action.HandActionType , outs.ToString() , couts , hr.ToString() , currentPotSize , action.Street , action.IsAggressiveAction , action.IsAllIn , action.IsAllInAction , action.IsBlinds , action.IsGameAction , action.IsPreFlopRaise , action.IsRaise , action.IsWinningsAction ); } } outputFile.Close(); } } catch (Exception ex) // Catch hand-parsing exceptions { Console.WriteLine("Parsing Error: {0}", ex.Message); // Example logging. Console.ReadLine(); } }
public Dictionary<Hand, int> ComputeOuts(Hand h, List<Card> holecards, List<Card> community, out Dictionary<Hand, List<Card>> whichouts) { Deck d = new Deck(); HandEvaluator he = new HandEvaluator(); Dictionary<Hand, int> handOuts = new Dictionary<Hand, int>(); Dictionary<Hand, List<Card>> handWhichOuts = new Dictionary<Hand, List<Card>>(); Dictionary<Hand, double> handRanks = new Dictionary<Hand, double>(); Dictionary<Hand, double> handWithoutCard = new Dictionary<Hand, double>(); // C# WHAT? This codes no works //List<string> testing = new List<string>(); //testing.Add("t"); //testing.Add("a"); //Console.WriteLine("{0}", testing); //testing.Remove("t"); //Console.WriteLine("{0}", testing); //return handOuts; // END This codes no works // initialize dict and remove visible cards to everyone. Outs are only computed on cards we can't see. handOuts.Add(h, 0); handWhichOuts.Add(h, new List<Card>()); d.RemoveCards(community); d.RemoveCards(holecards); // for every card left in the deck not visible, see which cards unilaterally improve hands positions relative to eachother // the card that produces a move to the best hand gets counted for that hand. foreach (Card c in d.DECK) { string handRank; double boardRankwith = 0.0; double boardRankwithout = 0.0; // Rank with card h.AddCard(c); //Console.WriteLine("NumCardsToRank: {0}\nMaxHandSize: {1}", h.NumCardsToRank, h.MaxHandSize); he = new HandEvaluator(); handRanks[h] = he.RankHand(h, out handRank); // Rank without card h.RemoveCard(c); he = new HandEvaluator(); handWithoutCard[h] = he.RankHand(h, out handRank); // Rank Board Cards if (community.Count > 0) { // board rank without card he = new HandEvaluator(); boardRankwithout = he.RankHand(new Hand(community, 7, 5), out handRank); // board rank with card he = new HandEvaluator(); community.Add(c); boardRankwith = he.RankHand(new Hand(community, 7, 5), out handRank); community.Remove(c); // Any card that increases your position one level and your position is at least 2 hand levels better than the board with the card. // we do two levels because if the board pairs and is a favorable pair to your hole cards, you hand will increase 2x. 2-pair -> board pairs -> full house. // all other cases should be handled by the if statement below. if ((Math.Round(handRanks[h], 2) > Math.Round(handWithoutCard[h], 2)) && (Math.Abs((int)handRanks[h] - (int)boardRankwith)) >= 2) { //Console.WriteLine("Card: {0}\nHoleCards: {1}\nCommunity: {2}\nHandRankWith: {3}\nHandRankWithout: {4}\nBoardRankWith: {5}\nBoardRankWithout: {6}", c.CardToString(), new Hand(holecards, 7,5).HandToString(), new Hand(community, 7 ,5).HandToString(), handRanks[h], handWithoutCard[h], boardRankwith, boardRankwithout); handOuts[h]++; handWhichOuts[h].Add(c); //Console.ReadLine(); } // The above if block does not catch all cases. If you have the same rank as the board but a higher pair, three kind, etc.. these are still favorable outs. // Example: Holecards: Ac2s Board: As5d5c // Board has a pair and you have a pair, but your pair is better. if (Math.Round(handRanks[h], 2) > Math.Round(boardRankwith, 2) && (Math.Round(handRanks[h], 2) > Math.Round(handWithoutCard[h], 2)) && (int)handRanks[h] == (int)boardRankwith && ((int)handRanks[h] == 4 || (int)handRanks[h] == 5 || (int)handRanks[h] == 8)) { // your hand is better than boards. You hand with the card is better than your previous hand. you have the same hand as the board. and the hand is a straight, flush, or straight flush. //Console.WriteLine("Card: {0}\nHoleCards: {1}\nCommunity: {2}\nHandRankWith: {3}\nHandRankWithout: {4}\nBoardRankWith: {5}\nBoardRankWithout: {6}", c.CardToString(), new Hand(holecards, 7, 5).HandToString(), new Hand(community, 7, 5).HandToString(), handRanks[h], handWithoutCard[h], boardRankwith, boardRankwithout); handOuts[h]++; handWhichOuts[h].Add(c); //Console.ReadLine(); } } //// who ever is the winner after this card is delt gets that out. //// this is more for people watching the play-by-play rather than analysis. Players only know what cards they can see. //foreach (KeyValuePair<Hand, double> kv in handRanksSort) //{ // handCurrentPosition[kv.Key] = handRanksSort.IndexOf(kv); // // keep a list of the number of outs and the actual cards which are considered outs for that hand. // handOuts[handRanksSort[0].Key]++; // handWhichOuts[handRanksSort[0].Key].Add(c); //} } whichouts = handWhichOuts; return handOuts; }
static void Main(string[] args) {// takes a full path to a directory that contains raw *.txt poker history files from 888 poker. IHandHistoryParserFactory handHistoryParserFactory = new HandHistoryParserFactoryImpl(); // Get the correct parser from the factory. var handHistoryParser = new Poker888FastParserImpl(); HandHistoryParserFastImpl fastParser = handHistoryParser as HandHistoryParserFastImpl; try { // The true causes hand-parse errors to get thrown. If this is false, hand-errors will // be silent and null will be returned. string[] files = Directory.GetFiles(args[0], "*.txt", SearchOption.AllDirectories); int fileCount = files.Length; foreach (string file in files) { Console.WriteLine("number of files left {0} out of {1}", fileCount--, files.Length); string fileText = new StreamReader(file).ReadToEnd(); var hands = fastParser.SplitUpMultipleHandsToLines(fileText); var outputFile = new StreamWriter(file + ".csv"); outputFile.WriteLine("DateOfHandUtc,HandId,DealerButtonPosition,TableName,GameDescription,NumPlayersActive,NumPlayersSeated,Rake,ComumnityCards,TotalPot,PlayerName,HoleCards,StartingStack,SeatNumber,ActionNumber,Amount,HandActionType,Outs,CardOuts,CurrentHandRank,currentPostSize,Street,IsAggressiveAction,IsAllIn,IsAllInAction,IsBlinds,IsGameAction,IsPreFlopRaise,IsRaise,IsWinningsAction"); foreach (var hand in hands) { var parsedHand = fastParser.ParseFullHandHistory(hand, true); // probably not the best way to do this. This should be added to the ParseHandActions function or something. decimal currentPotSize = 0; int actionNumber = 0; foreach (var action in parsedHand.HandActions) { // I tried to do this (this = 'actionNumber++') rtdfgcvdrt properly via the ParseHandActions function in Poker888FastParserImpl.cs file to be 1-1 with the raw handlines, however // I was getting some un-expected behavior when the action was all in and the winning action the handline index would be 0 so you would end up with // actions sequences like 1,2,3,4,5,6,0,8,9,10. actionNumber++; if (action.HandActionType == HandHistories.Objects.Actions.HandActionType.ANTE || action.HandActionType == HandHistories.Objects.Actions.HandActionType.BET || action.HandActionType == HandHistories.Objects.Actions.HandActionType.SMALL_BLIND || action.HandActionType == HandHistories.Objects.Actions.HandActionType.RAISE || action.HandActionType == HandHistories.Objects.Actions.HandActionType.BIG_BLIND || action.HandActionType == HandHistories.Objects.Actions.HandActionType.CALL || action.HandActionType == HandHistories.Objects.Actions.HandActionType.ALL_IN) { currentPotSize += action.Amount; } // Don't judge me.... this code is just chaos...but it's works. string handRank; HandEvaluator.HandEvaluator he = new HandEvaluator.HandEvaluator(); string handstring = String.Format("{0}{1}", parsedHand.Players.First(p => p.PlayerName.Equals(action.PlayerName)).HoleCards, parsedHand.ComumnityCards); string flopstring; string turnstring; string riverstring; string currenthandstring; Hand h = new Hand(); // holecards Hand hc = new Hand(); Dictionary <Hand, int> handOuts = new Dictionary <Hand, int>(); Dictionary <Hand, List <Card> > cardouts; int outs = 0; double hr = 0.0; string couts = ""; if (handstring.Length >= 14) { currenthandstring = ""; flopstring = handstring.Substring(4, 6); turnstring = handstring.Substring(10, 2); riverstring = handstring.Substring(12, 2); // build the hand play-by-play so we can get current hand ranking and also build in hand outs. switch (action.Street) { case HandHistories.Objects.Cards.Street.Flop: currenthandstring = handstring.Substring(0, 4) + flopstring; h = new Hand(currenthandstring, 7, 5); hc = new Hand(handstring.Substring(0, 4), 7, 5); hr = he.RankHand(h, out handRank); handOuts = he.ComputeOuts(h, hc.HAND, new Hand(flopstring, 7, 5).HAND, out cardouts); outs = handOuts[h]; couts = new Hand(cardouts[h], 52, 5).HandToString(); break; case HandHistories.Objects.Cards.Street.Turn: currenthandstring = handstring.Substring(0, 4) + flopstring + turnstring; h = new Hand(currenthandstring, 7, 5); hc = new Hand(handstring.Substring(0, 4), 7, 5); hr = he.RankHand(h, out handRank); handOuts = he.ComputeOuts(h, hc.HAND, new Hand(flopstring + turnstring, 7, 5).HAND, out cardouts); outs = handOuts[h]; couts = new Hand(cardouts[h], 52, 5).HandToString(); break; case HandHistories.Objects.Cards.Street.River: currenthandstring = handstring.Substring(0, 4) + flopstring + turnstring + riverstring; h = new Hand(currenthandstring, 7, currenthandstring.Length / 2); hc = new Hand(handstring.Substring(0, 4), 7, 5); hr = he.RankHand(h, out handRank); outs = 0; // No need to compute outs on the river. No more cards to come. break; default: hr = 0.0; outs = 0; break; } } else { hr = 0.0; outs = 0; } outputFile.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21},{22},{23},{24},{25},{26},{27},{28},{29}", parsedHand.DateOfHandUtc , parsedHand.HandId , parsedHand.DealerButtonPosition , parsedHand.TableName , parsedHand.GameDescription , parsedHand.NumPlayersActive , parsedHand.NumPlayersSeated , parsedHand.Rake , parsedHand.ComumnityCards , parsedHand.TotalPot , action.PlayerName , parsedHand.Players.First(p => p.PlayerName.Equals(action.PlayerName)).HoleCards , parsedHand.Players.First(p => p.PlayerName.Equals(action.PlayerName)).StartingStack , parsedHand.Players.First(p => p.PlayerName.Equals(action.PlayerName)).SeatNumber , actionNumber , action.Amount , action.HandActionType , outs.ToString() , couts , hr.ToString() , currentPotSize , action.Street , action.IsAggressiveAction , action.IsAllIn , action.IsAllInAction , action.IsBlinds , action.IsGameAction , action.IsPreFlopRaise , action.IsRaise , action.IsWinningsAction ); } } outputFile.Close(); } } catch (Exception ex) // Catch hand-parsing exceptions { Console.WriteLine("Parsing Error: {0}", ex.Message); // Example logging. Console.ReadLine(); } }