From bc1814eb643b9bd82f1bf7f76ab764011734526c Mon Sep 17 00:00:00 2001 From: RZ Date: Wed, 29 Nov 2023 19:18:12 -0500 Subject: [PATCH 1/7] Add new test file --- .../HandHistories.Parser.UnitTests.csproj | 3 ++ .../CashGame/GeneralHands/ReceivesCashout.txt | 43 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 HandHistories.Parser.UnitTests/SampleHandHistories/GGPoker/CashGame/GeneralHands/ReceivesCashout.txt diff --git a/HandHistories.Parser.UnitTests/HandHistories.Parser.UnitTests.csproj b/HandHistories.Parser.UnitTests/HandHistories.Parser.UnitTests.csproj index 246e097..c395206 100644 --- a/HandHistories.Parser.UnitTests/HandHistories.Parser.UnitTests.csproj +++ b/HandHistories.Parser.UnitTests/HandHistories.Parser.UnitTests.csproj @@ -389,6 +389,9 @@ Always + + Always + Always diff --git a/HandHistories.Parser.UnitTests/SampleHandHistories/GGPoker/CashGame/GeneralHands/ReceivesCashout.txt b/HandHistories.Parser.UnitTests/SampleHandHistories/GGPoker/CashGame/GeneralHands/ReceivesCashout.txt new file mode 100644 index 0000000..16ca0db --- /dev/null +++ b/HandHistories.Parser.UnitTests/SampleHandHistories/GGPoker/CashGame/GeneralHands/ReceivesCashout.txt @@ -0,0 +1,43 @@ +Poker Hand #HD2281523: Hold'em No Limit ($0.25/$0.5) - 2019/01/11 09:15:06 +Table 'NLHBronze21' 6-max Seat #1 is the button +Seat 1: c12290be ($22 in chips) +Seat 2: 1xfd8bbx ($123.61 in chips) +Seat 3: 88989dfa ($116.2 in chips) +Seat 4: fdfa4dax ($7 in chips) +Seat 5: fdac21ts ($52.5 in chips) +Seat 6: Hero ($95.82 in chips) +1xfd8bbx: posts small blind $0.25 +88989dfa: posts big blind $0.5 +*** HOLE CARDS *** +Dealt to c12290be +Dealt to 1xfd8bbx +Dealt to 88989dfa +Dealt to fdfa4dax +Dealt to fdac21ts +Dealt to Hero [2h 8h] +fdfa4dax: calls $0.5 +fdac21ts: raises $1.32 to $1.82 +Hero: folds +c12290be: folds +1xfd8bbx: folds +88989dfa: calls $1.32 +fdfa4dax: raises $5.18 to $7 and is all-in +fdac21ts: folds +88989dfa: calls $5.18 +fdfa4dax: shows [Ah 5h] +88989dfa: shows [6s 6d] +*** FLOP *** [Ts Qc 4d] +*** TURN *** [Ts Qc 4d] [9h] +*** RIVER *** [Ts Qc 4d 9h] [Ac] +88989dfa: Receives Cashout ($9.98) +*** SHOWDOWN *** +fdfa4dax collected $14.8 from pot +*** SUMMARY *** +Total pot $16.07 | Rake $0.77 | Jackpot $0.5 | Bingo $0 +Board [Ts Qc 4d 9h Ac] +Seat 1: c12290be (button) folded before Flop (didn't bet) +Seat 2: 1xfd8bbx (small blind) folded before Flop +Seat 3: 88989dfa (big blind) showed [6s 6d] and lost with Pair of Sixes, EV Cashout ($9.98) +Seat 4: fdfa4dax showed [Ah 5h] and won ($14.8) with Pair of Aces +Seat 5: fdac21ts folded before Flop +Seat 6: Hero folded before Flop (didn't bet) \ No newline at end of file From 637aabb46374aa53c54c3965e03c0437cb7c0a8f Mon Sep 17 00:00:00 2001 From: RZ Date: Wed, 29 Nov 2023 19:38:07 -0500 Subject: [PATCH 2/7] Adding the new unit test --- .../GGPokerHandSummaryParserExtraTests.cs | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs index d2d6b05..95e8348 100644 --- a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs +++ b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs @@ -556,5 +556,78 @@ public void RunThreeTimes() TestFullHandHistorySummary(expectedSummary, "RunThreeTimes"); TestHandHistory(expectedHandHistory, "RunThreeTimes"); } + + [Test] + public void ReceivesCashout() + { + HandHistorySummary expectedSummary = new HandHistorySummary() + { + GameDescription = new GameDescriptor() + { + PokerFormat = PokerFormat.CashGame, + GameType = GameType.NoLimitHoldem, + Limit = Limit.FromSmallBlindBigBlind(0.25m, 0.5m, Currency.USD), + SeatType = SeatType.FromMaxPlayers(6), + Site = SiteName.GGPoker, + TableType = TableType.FromTableTypeDescriptions(TableTypeDescription.Regular) + }, + DateOfHandUtc = new DateTime(2019, 1, 11, 9, 15, 6), + DealerButtonPosition = 1, + HandId = HandID.From(2281523), + NumPlayersSeated = 6, + TableName = "NLHBronze21", + TotalPot = 16.07m, + Rake = 0.77m, + Jackpot = 0.5m, + Bingo = 0 + }; + HandHistory expectedHandHistory = new HandHistory() + { + CommunityCards = BoardCards.FromCards("TsQc4d9hAc"), + Players = new PlayerList(new List + { + new Player("c12290be", 22, 1), + new Player("1xfd8bbx", 123.61m, 2), + new Player("88989dfa", 116.2m, 3, HoleCards.FromCards("6s6d")), + new Player("fdfa4dax", 7, 4, HoleCards.FromCards("Ah5h")), + new Player("fdac21ts", 52.5m, 5), + new Player("Hero", 95.82m, 6, HoleCards.FromCards("2h8h")), + }), + Hero = new Player("Hero",95.82m, 6, HoleCards.FromCards("2h8h")), + RunItMultipleTimes = new RunItTwice[] + { + new RunItTwice + { + Board = BoardCards.FromCards("TsQc4d9hAc"), + Actions = new List { }, + Winners = new List + { + new WinningsAction("fdfa4dax", WinningsActionType.WINS, 14.8m, 0) + } + }, + new RunItTwice {}, + new RunItTwice {} + }, + Winners = new List() { new WinningsAction("fdfa4dax", WinningsActionType.WINS, 14.8m, 0)}, + HandActions = new List() { + new HandAction("1xfd8bbx", HandActionType.SMALL_BLIND, -0.25m, Street.Preflop), + new HandAction("88989dfa", HandActionType.BIG_BLIND, -0.5m, Street.Preflop), + new HandAction("fdfa4dax", HandActionType.CALL, 0.5m, Street.Preflop), + new HandAction("fdac21ts", HandActionType.RAISE, 1.82m, Street.Preflop), + new HandAction("Hero", HandActionType.FOLD, 0, Street.Preflop), + new HandAction("c12290be", HandActionType.FOLD, 0, Street.Preflop), + new HandAction("1xfd8bbx", HandActionType.FOLD, 0, Street.Preflop), + new HandAction("88989dfa", HandActionType.CALL, 1.32m, Street.Preflop), + new HandAction("fdfa4dax", HandActionType.RAISE, 6.5m, Street.Preflop, true), + new HandAction("fdac21ts", HandActionType.FOLD, 0, Street.Preflop), + new HandAction("88989dfa", HandActionType.CALL, 5.18m, Street.Preflop), + new HandAction("fdfa4dax", HandActionType.SHOW, Street.Showdown), + new HandAction("88989dfa", HandActionType.SHOW, Street.Showdown) + } + }; + + TestFullHandHistorySummary(expectedSummary, "ReceivesCashout"); + TestHandHistory(expectedHandHistory, "ReceivesCashout"); + } } } From 0e96006743415866bfed427c6f304288b5f29da8 Mon Sep 17 00:00:00 2001 From: RZ Date: Wed, 29 Nov 2023 21:10:34 -0500 Subject: [PATCH 3/7] Add new enum for cashout --- HandHistories.Objects/Actions/WinningsActionType.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/HandHistories.Objects/Actions/WinningsActionType.cs b/HandHistories.Objects/Actions/WinningsActionType.cs index 229653c..b5baf5a 100644 --- a/HandHistories.Objects/Actions/WinningsActionType.cs +++ b/HandHistories.Objects/Actions/WinningsActionType.cs @@ -12,5 +12,6 @@ public enum WinningsActionType WINS_SIDE_POT, TIES, TIES_SIDE_POT, + CASHOUT, } } From 5a845f99ebd6aec82aa85c1167076f8ca72a04eb Mon Sep 17 00:00:00 2001 From: RZ Date: Wed, 29 Nov 2023 21:11:14 -0500 Subject: [PATCH 4/7] Add handling for "Receives Cashout" --- .../GGPoker/GGPokerFastParserImpl.cs | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs b/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs index 61112db..b20030b 100644 --- a/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs +++ b/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs @@ -268,7 +268,12 @@ public void ParseShowDown(string[] handLines, List handActions, List throw new ArgumentException("Unhandled line: " + line); } // 1234abcd: shows[4d 3d] (Pair of Fours) + // 88989dfa: Receives Cashout ($9.98) case ')': + if (line.Contains("Receives Cashout")) + { + winners.Add(ParseWinnings(line)); + } break; @@ -859,16 +864,34 @@ private BoardCards ParseBoard(string line, BoardCards baseBoard) public WinningsAction ParseWinnings(string line) { - // 12b64606 collected $2.5 from pot - int firstSpaceIndex = line.IndexOf(" collected"); - int dollarSignIndex = line.LastIndexOf('$'); - int amountEndingIndex = line.Length - 8; + if (line.Contains("collected")) + { + // 12b64606 collected $2.5 from pot + int firstSpaceIndex = line.IndexOf(" collected"); + int dollarSignIndex = line.LastIndexOf('$'); + int amountEndingIndex = line.Length - 8; + + string playerName = line.Substring(0, firstSpaceIndex); + string amount = line.Substring(dollarSignIndex, amountEndingIndex - dollarSignIndex - 1); + + // 0 for main pot. In gg hand history, it does not show side pot information. + return new WinningsAction(playerName, WinningsActionType.WINS, amount.ParseAmount(), 0); + } + else if (line.Contains("Receives Cashout")) + { + // xyz: Receives Cashout ($9.98) + int lastOpenBracketIndex = line.LastIndexOf('('); + int colonIndex = line.LastIndexOf(":"); - string playerName = line.Substring(0, firstSpaceIndex); - string amount = line.Substring(dollarSignIndex, amountEndingIndex - dollarSignIndex - 1); + string playerName = line.Substring(0, colonIndex); + string amount = line.Substring(lastOpenBracketIndex + 1, line.Length - lastOpenBracketIndex - 3); - // 0 for main pot. In gg hand history, it does not show side pot information. - return new WinningsAction(playerName, WinningsActionType.WINS, amount.ParseAmount(), 0); + return new WinningsAction(playerName, WinningsActionType.CASHOUT, amount.ParseAmount(), 0); + } + else + { + throw new Exception("Unknown winning line: " + line); + } } private Currency ParseCurrency(string handLine, char currencySymbol) From 15390bc652ddff25218439dc64ff14bcf7eca73e Mon Sep 17 00:00:00 2001 From: RZ Date: Wed, 29 Nov 2023 22:29:11 -0500 Subject: [PATCH 5/7] Add action line unit tests for receives cashout --- .../GGPoker/GGPokerFastParserActionTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerFastParserActionTests.cs b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerFastParserActionTests.cs index 8d6f5be..c32b50b 100644 --- a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerFastParserActionTests.cs +++ b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerFastParserActionTests.cs @@ -148,6 +148,15 @@ public void ParseWinnings_WithColon_Works() Assert.AreEqual(new WinningsAction("wo_olly:D", WinningsActionType.WINS, 0.57m, 0), handAction); } + [Test] + public void ParseWinnings_ReceivesCashOut_Works() + { + WinningsAction handAction = + GetGGPokerFastParser().ParseWinnings(@"wo_olly:D: Receives Cashout ($9.98)"); + + Assert.AreEqual(new WinningsAction("wo_olly:D", WinningsActionType.CASHOUT, 9.98m, 0), handAction); + } + [Test] public void ParseMiscShowdownLine_Shows_Works() { From 955483cd505560a83ad0cd04d446d8d4147361ba Mon Sep 17 00:00:00 2001 From: RZ Date: Wed, 29 Nov 2023 22:29:58 -0500 Subject: [PATCH 6/7] Add the parsing in the right place + fix unit tests --- .../GGPokerHandSummaryParserExtraTests.cs | 11 +++++-- .../GGPoker/GGPokerFastParserImpl.cs | 30 ++++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs index 95e8348..84133e4 100644 --- a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs +++ b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs @@ -602,13 +602,18 @@ public void ReceivesCashout() Actions = new List { }, Winners = new List { - new WinningsAction("fdfa4dax", WinningsActionType.WINS, 14.8m, 0) + new WinningsAction("88989dfa", WinningsActionType.CASHOUT, 9.98m, 0), + new WinningsAction("fdfa4dax", WinningsActionType.WINS, 14.8m, 0), } }, new RunItTwice {}, new RunItTwice {} }, - Winners = new List() { new WinningsAction("fdfa4dax", WinningsActionType.WINS, 14.8m, 0)}, + Winners = new List() + { + new WinningsAction("88989dfa", WinningsActionType.CASHOUT, 9.98m, 0), + new WinningsAction("fdfa4dax", WinningsActionType.WINS, 14.8m, 0) + }, HandActions = new List() { new HandAction("1xfd8bbx", HandActionType.SMALL_BLIND, -0.25m, Street.Preflop), new HandAction("88989dfa", HandActionType.BIG_BLIND, -0.5m, Street.Preflop), @@ -622,7 +627,7 @@ public void ReceivesCashout() new HandAction("fdac21ts", HandActionType.FOLD, 0, Street.Preflop), new HandAction("88989dfa", HandActionType.CALL, 5.18m, Street.Preflop), new HandAction("fdfa4dax", HandActionType.SHOW, Street.Showdown), - new HandAction("88989dfa", HandActionType.SHOW, Street.Showdown) + new HandAction("88989dfa", HandActionType.SHOW, Street.Showdown), } }; diff --git a/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs b/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs index b20030b..187a40e 100644 --- a/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs +++ b/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs @@ -268,12 +268,7 @@ public void ParseShowDown(string[] handLines, List handActions, List throw new ArgumentException("Unhandled line: " + line); } // 1234abcd: shows[4d 3d] (Pair of Fours) - // 88989dfa: Receives Cashout ($9.98) case ')': - if (line.Contains("Receives Cashout")) - { - winners.Add(ParseWinnings(line)); - } break; @@ -585,6 +580,17 @@ public override RunItTwice[] ParseMultipleRuns(string[] handLines) multipleRuns[currentBoard].Winners.Add(ParseWinnings(line)); } + // expect to look like this: + // xyz: Receives Cashout ($9.98) + // + // Player who chooses to cashout will not have multiple runs. + // Store the info on the first board. + if (line.Contains("Receives Cashout")) + { + line = handLines[i]; + multipleRuns[0].Winners.Add(ParseWinnings(line)); + } + // *** SHOWDOWN *** // *** FIRST SHOWDOWN *** // *** SECOND SHOWDOWN *** @@ -670,7 +676,15 @@ private bool ParseLine(string line, ref Street currentStreet, List h case 's': if (line.EndsWithFast(" folds") || line.EndsWithFast(" checks")) { break; } goto default; - + + // xyz: Receives Cashout ($9.98) + case ')': + if (line.Contains("Receives Cashout")) + { + break; + } + goto default; + default: return false; } @@ -684,7 +698,7 @@ private bool ParseLine(string line, ref Street currentStreet, List h throw new HandActionException("", "Invalid State: Street"); default: - if (colonIndex > -1 && line[line.Length - 1] != 't') + if (colonIndex > -1 && !line.Contains("Receives Cashout")) { handActions.Add(ParseRegularActionLine(line, colonIndex, currentStreet)); } @@ -884,7 +898,7 @@ public WinningsAction ParseWinnings(string line) int colonIndex = line.LastIndexOf(":"); string playerName = line.Substring(0, colonIndex); - string amount = line.Substring(lastOpenBracketIndex + 1, line.Length - lastOpenBracketIndex - 3); + string amount = line.Substring(lastOpenBracketIndex + 1, line.Length - lastOpenBracketIndex - 2); return new WinningsAction(playerName, WinningsActionType.CASHOUT, amount.ParseAmount(), 0); } From 81cc16f0ccc9e457a58cb3056376d3dec740fed4 Mon Sep 17 00:00:00 2001 From: RZ Date: Thu, 30 Nov 2023 12:56:51 -0500 Subject: [PATCH 7/7] Change the name from cashout to Insurance --- HandHistories.Objects/Actions/WinningsActionType.cs | 2 +- .../FastParserTests/GGPoker/GGPokerFastParserActionTests.cs | 2 +- .../GGPoker/GGPokerHandSummaryParserExtraTests.cs | 4 ++-- .../Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/HandHistories.Objects/Actions/WinningsActionType.cs b/HandHistories.Objects/Actions/WinningsActionType.cs index b5baf5a..f89c39b 100644 --- a/HandHistories.Objects/Actions/WinningsActionType.cs +++ b/HandHistories.Objects/Actions/WinningsActionType.cs @@ -12,6 +12,6 @@ public enum WinningsActionType WINS_SIDE_POT, TIES, TIES_SIDE_POT, - CASHOUT, + INSURANCE, } } diff --git a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerFastParserActionTests.cs b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerFastParserActionTests.cs index 14fb392..e80f2db 100644 --- a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerFastParserActionTests.cs +++ b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerFastParserActionTests.cs @@ -175,7 +175,7 @@ public void ParseWinnings_ReceivesCashOut_Works() WinningsAction handAction = GetGGPokerFastParser().ParseWinnings(@"wo_olly:D: Receives Cashout ($9.98)"); - Assert.AreEqual(new WinningsAction("wo_olly:D", WinningsActionType.CASHOUT, 9.98m, 0), handAction); + Assert.AreEqual(new WinningsAction("wo_olly:D", WinningsActionType.INSURANCE, 9.98m, 0), handAction); } [Test] diff --git a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs index 8774e0e..b4cf89d 100644 --- a/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs +++ b/HandHistories.Parser.UnitTests/Parsers/FastParserTests/GGPoker/GGPokerHandSummaryParserExtraTests.cs @@ -675,7 +675,7 @@ public void ReceivesCashout() Actions = new List { }, Winners = new List { - new WinningsAction("88989dfa", WinningsActionType.CASHOUT, 9.98m, 0), + new WinningsAction("88989dfa", WinningsActionType.INSURANCE, 9.98m, 0), new WinningsAction("fdfa4dax", WinningsActionType.WINS, 14.8m, 0), } }, @@ -684,7 +684,7 @@ public void ReceivesCashout() }, Winners = new List() { - new WinningsAction("88989dfa", WinningsActionType.CASHOUT, 9.98m, 0), + new WinningsAction("88989dfa", WinningsActionType.INSURANCE, 9.98m, 0), new WinningsAction("fdfa4dax", WinningsActionType.WINS, 14.8m, 0) }, HandActions = new List() { diff --git a/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs b/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs index e5bdd2b..1f9c26f 100644 --- a/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs +++ b/HandHistories.Parser/Parsers/FastParser/GGPoker/GGPokerFastParserImpl.cs @@ -906,7 +906,7 @@ public WinningsAction ParseWinnings(string line) string playerName = line.Substring(0, colonIndex); string amount = line.Substring(lastOpenBracketIndex + 1, line.Length - lastOpenBracketIndex - 2); - return new WinningsAction(playerName, WinningsActionType.CASHOUT, amount.ParseAmount(), 0); + return new WinningsAction(playerName, WinningsActionType.INSURANCE, amount.ParseAmount(), 0); } else {