private static void CheckAllHandActionsForUncalled(IList<HandAction> handActions, int index) { var lastAgrassiveAction = handActions.LastOrDefault(ha => ha.HandActionType == HandActionType.BET || ha.HandActionType == HandActionType.RAISE || ha.HandActionType == HandActionType.ALL_IN_RAISE); if (lastAgrassiveAction == null) return; var ind = handActions.IndexOf(lastAgrassiveAction); for (var i = ind; i < handActions.Count; i++) { if (handActions[i].HandActionType == HandActionType.CALL || handActions[i].HandActionType == HandActionType.ALL_IN_CALL) return; } var uncalledBetHandAction = new HandAction { Index = index, PlayerName = lastAgrassiveAction.PlayerName, HandActionType = HandActionType.UNCALLED_BET, Street = lastAgrassiveAction.Street, Amount = -lastAgrassiveAction.Amount }; handActions.Add(uncalledBetHandAction); }
public override IEnumerable<HandAction> ParseHandActions(Game game, IReadOnlyList<string> multipleLines) { var handActions = new List<HandAction>(); var currentStreet = Street.Preflop; for (var i = StartPlayerRow + game.NumberOfPlayers; i < multipleLines.Count; i++) { var ha = new HandAction() { Index = i }; var lowerLine = multipleLines[i].ToLower(); if (multipleLines[i].StartsWith("**")) { if (lowerLine.Contains("flop")) { game.BoardCards.InitializeNewCards(FindFlopCards(multipleLines[i])); currentStreet = Street.Flop; continue; } if (lowerLine.Contains("turn")) { game.BoardCards[3] = FindTurnCard(multipleLines[i]); currentStreet = Street.Turn; continue; } if (lowerLine.Contains("river")) { game.BoardCards[4] = FindRiverCard(multipleLines[i]); currentStreet = Street.River; continue; } if (lowerLine.Contains("down cards")) { continue; } if (lowerLine.Contains("summary")) { currentStreet = Street.Showdown; continue; } throw new ParserException($"No defined action with **. Unnown line -> {multipleLines[i]}", DateTime.Now); }//end ** if (lowerLine.StartsWith("dealt to")) { ha.PlayerName = multipleLines[i].Split(' ')[2].Trim(); ha.Street = currentStreet; ha.HandActionType = HandActionType.DEALT_HERO_CARDS; game.Hero = ha.PlayerName; game.PlayerHistories.Find(p => p.PlayerName == ha.PlayerName).HoleCards.InitializeNewCards(FindHeroCards(multipleLines[i])); handActions.Add(ha); continue; } //line don't starts with ** and "dealt to" //put new conditional in this place if some new statemants will apear //..... //..... var parts = multipleLines[i].Split(' '); ha.PlayerName = parts[0].Trim(); ha.Street = currentStreet; switch (parts[1].Trim()) { case "posts": switch (parts[2].Trim()) { case "big": ha.HandActionType = HandActionType.BIG_BLIND; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); break; case "small": ha.HandActionType = HandActionType.SMALL_BLIND; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); break; case "ante": ha.HandActionType = HandActionType.ANTE; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); break; case "dead": ha.HandActionType = HandActionType.DEAD_BLIND; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); break; default: throw new ParserException($"Undefined action. Unnown line -> {multipleLines[i]}", DateTime.Now); } continue; case "folds": ha.HandActionType = HandActionType.FOLD; handActions.Add(ha); continue; case "checks": ha.HandActionType = HandActionType.CHECK; handActions.Add(ha); continue; case "calls": ha.HandActionType = HandActionType.CALL; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; case "bets": ha.HandActionType = HandActionType.BET; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; case "raises": ha.HandActionType = HandActionType.RAISE; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; case "shows": ha.HandActionType = HandActionType.SHOW; game.PlayerHistories.Find(p => p.PlayerName == ha.PlayerName).HoleCards.InitializeNewCards(FindShowdounCards(multipleLines[i])); handActions.Add(ha); continue; case "mucks": ha.HandActionType = HandActionType.MUCKS; game.PlayerHistories.Find(p => p.PlayerName == ha.PlayerName).HoleCards.InitializeNewCards(FindMuckCards(multipleLines[i])); handActions.Add(ha); continue; case "collected": ha.HandActionType = HandActionType.WINS; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; } } CheckAllHandActionsForUncalled(handActions, multipleLines.Count); return handActions; }
protected virtual double DefineActionAmount(HandAction handAction, string inputLine) { var match = ActionAmountRegex.Match(inputLine).Value; var amount = GetCleanAmount(match); switch (handAction.HandActionType) { case HandActionType.BET: case HandActionType.BIG_BLIND: case HandActionType.SMALL_BLIND: case HandActionType.DEAD_BLIND: case HandActionType.CALL: case HandActionType.ALL_IN_CALL: case HandActionType.ALL_IN_RAISE: case HandActionType.All_IN_BB: case HandActionType.All_IN_SB: case HandActionType.ANTE: case HandActionType.RAISE: return -amount; case HandActionType.WINS: case HandActionType.WINS_SIDE_POT: case HandActionType.WINS_MAIN_POT: //case HandActionType.UNCALLED_BET: return amount; } throw new Exception("Undefined amount action!"); }
public override IEnumerable<HandAction> ParseHandActions(Game game, IReadOnlyList<string> multipleLines) { var handActions = new List<HandAction>(); var currentStreet = Street.Preflop; for (var i = StartPlayerRow + game.NumberOfPlayers; i < multipleLines.Count; i++) { var ha = new HandAction() { Index = i }; var lowerLine = multipleLines[i].ToLower(); if (multipleLines[i].StartsWith("***")) { if (lowerLine.Contains("flop")) { game.BoardCards.InitializeNewCards(FindFlopCards(multipleLines[i])); currentStreet = Street.Flop; continue; } if (lowerLine.Contains("turn")) { game.BoardCards[3] = FindTurnCard(multipleLines[i]); currentStreet = Street.Turn; continue; } if (lowerLine.Contains("river")) { game.BoardCards[4] = FindRiverCard(multipleLines[i]); currentStreet = Street.River; continue; } if (lowerLine.Contains("hole")) { continue; } if (lowerLine.Contains("show down")) { currentStreet = Street.Showdown; continue; } if (lowerLine.Contains("summary")) { break;//пока что summary строки не будем обрабатывать. } throw new ParserException($"No defined action with ***. Unnown line -> {multipleLines[i]}", DateTime.Now); } //end *** if (lowerLine.StartsWith("dealt to")) { ha.PlayerName = HeroNameRegex.Match(multipleLines[i]).Value.Trim(); ha.Street = currentStreet; ha.HandActionType = HandActionType.DEALT_HERO_CARDS; game.Hero = ha.PlayerName; game.PlayerHistories.Find(p => p.PlayerName == ha.PlayerName).HoleCards.InitializeNewCards(FindHeroCards(multipleLines[i])); handActions.Add(ha); continue; } //hand actions of type "player:action" if (multipleLines[i].Contains(':')) { var parts = multipleLines[i].Split(':'); ha.PlayerName = parts[0].Trim(); ha.Street = currentStreet; var actionParts = parts[1].Trim().Split(' '); switch (actionParts[0]) { case "posts": var key = actionParts[1]; switch (key) { case "big": ha.HandActionType = multipleLines[i].Contains("all-in") ? HandActionType.All_IN_BB : HandActionType.BIG_BLIND; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); break; case "small": ha.HandActionType = multipleLines[i].Contains("all-in") ? HandActionType.All_IN_SB : HandActionType.SMALL_BLIND; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); break; case "the"://ante ha.HandActionType = HandActionType.ANTE; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); break; default: throw new ParserException( $"No defined action that contains posts. Unnown line -> {multipleLines[i]}", DateTime.Now); } continue; case "folds": ha.HandActionType = HandActionType.FOLD; handActions.Add(ha); continue; case "checks": ha.HandActionType = HandActionType.CHECK; handActions.Add(ha); continue; case "calls": ha.HandActionType = multipleLines[i].Contains("all-in") ? HandActionType.ALL_IN_CALL : HandActionType.CALL; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; case "bets": ha.HandActionType = multipleLines[i].Contains("all-in") ? HandActionType.ALL_IN_BET : HandActionType.BET; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; case "raises": ha.HandActionType = multipleLines[i].Contains("all-in") ? HandActionType.ALL_IN_RAISE : HandActionType.RAISE; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; case "doesn't": ha.HandActionType = HandActionType.DIDNT_SHOW_HAND; handActions.Add(ha); continue; case "shows": ha.HandActionType = HandActionType.SHOW; game.PlayerHistories.Find(p => p.PlayerName == ha.PlayerName).HoleCards.InitializeNewCards(FindShowdounCards(multipleLines[i])); handActions.Add(ha); continue; case "mucks": ha.HandActionType = HandActionType.MUCKS; game.PlayerHistories.Find(p => p.PlayerName == ha.PlayerName).HoleCards.InitializeNewCards(FindMuckCards(multipleLines)); handActions.Add(ha); continue; default: throw new ParserException( $"Cann't parse string with ':' and unnown word. Unnown line -> {multipleLines[i]}", DateTime.Now); } } //end contains : if (lowerLine.Contains("uncalled bet")) { ha.HandActionType = HandActionType.UNCALLED_BET; ha.PlayerName = UncalledBetPlayerRegex.Match(multipleLines[i]).Value; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; } if (lowerLine.Contains("collected")) { if (lowerLine.Contains("main")) { ha.HandActionType = HandActionType.WINS_MAIN_POT; } else if (lowerLine.Contains("side")) { ha.HandActionType = HandActionType.WINS_SIDE_POT; } else { ha.HandActionType = HandActionType.WINS; } ha.PlayerName = WinPlayerRegex.Match(multipleLines[i]).Value; ha.Amount = DefineActionAmount(ha, multipleLines[i]); handActions.Add(ha); continue; } //hand actions without tracking: if (lowerLine.Contains("leaves the table")) { continue; } if (lowerLine.Contains("joins the table")) { continue; } if (lowerLine.Contains("will be allowed to play")) { continue; } if (lowerLine.Contains("is disconnected")) { continue; } if (lowerLine.Contains("was removed from the table")) { continue; } if (lowerLine.Contains("finished the tournament")) { continue; } if (lowerLine.Contains("said,")) { continue; } if (lowerLine.Contains("has timed out")) { continue; } if (lowerLine.Contains("is connected")) { continue; } if (lowerLine.Contains("bounty for eliminating")) { continue; } throw new ParserException($"Line with a new words -> {multipleLines[i]}", DateTime.Now); } return handActions; }
//todo:need to test protected virtual double DefineActionAmount(HandAction handAction, string inputLine) { string strAmout; switch (handAction.HandActionType) { case HandActionType.ALL_IN_CALL: strAmout = AllInCallAmountRegex.Match(inputLine).Value; break; case HandActionType.ALL_IN_RAISE: strAmout = AllInRaiseAmountRegex.Match(inputLine).Value; break; case HandActionType.ALL_IN_BET: strAmout = AllInBetAmountRegex.Match(inputLine).Value; break; case HandActionType.WINS: strAmout = CollectedPotRegex.Match(inputLine).Value; break; case HandActionType.WINS_MAIN_POT: strAmout = CollectedMainPotRegex.Match(inputLine).Value; break; case HandActionType.WINS_SIDE_POT: strAmout = CollectedSidePotRegex.Match(inputLine).Value; break; case HandActionType.UNCALLED_BET: strAmout = UncalledBetAmountRegex.Match(inputLine).Value; break; case HandActionType.ANTE: strAmout = AnteAmountRegex.Match(inputLine).Value; break; case HandActionType.All_IN_BB: case HandActionType.All_IN_SB: strAmout = AllInBlindsAmountRegex.Match(inputLine).Value; break; default: strAmout = inputLine.Split(' ').Last(); break; } var amount = GetCleanAmount(strAmout); switch (handAction.HandActionType) { case HandActionType.BET: case HandActionType.BIG_BLIND: case HandActionType.SMALL_BLIND: case HandActionType.CALL: case HandActionType.ALL_IN_CALL: case HandActionType.ALL_IN_BET: case HandActionType.ALL_IN_RAISE: case HandActionType.All_IN_BB: case HandActionType.All_IN_SB: case HandActionType.ANTE: case HandActionType.RAISE: return -amount; case HandActionType.WINS: case HandActionType.WINS_SIDE_POT: case HandActionType.WINS_MAIN_POT: case HandActionType.UNCALLED_BET://неотвечена ставка возвращается с положительным знаком return amount; } throw new Exception("Undefined amount action!"); }
/// <summary> /// Ф:Перед использованием произвести фильтрацию по улице! /// </summary> public static bool AllFoldedBeforeAction(this IEnumerable<HandAction> actions, HandAction actionBefore) { var beforeActions = actions.Where(a => a.Index < actionBefore.Index).NotBlinds(); return beforeActions.RealActionsAndBlinds().All(a => a.HandActionType == HandActionType.FOLD || a.HandActionType == HandActionType.CHECK);//check when dead blind }
public static PlayerHistory GetPlayerHistoryForAction(this Game game, HandAction ha) { return game.PlayerHistories.FirstOrDefault(ph => ph.PlayerName== ha.PlayerName); }