public Player(string playerName, decimal startingStack, int seatNumber) { PlayerName = playerName; StartingStack = startingStack; SeatNumber = seatNumber; HoleCards = HoleCards.NoHolecards(playerName); }
private HoleCards ParseHoleCards(string handText, string playerName) { try { string regexString = GetHoleCardsRegex(playerName); var regex = Regex.Match(handText, regexString); if (regex.Success) { return(HoleCards.FromCards(playerName, CardGroup.Parse(regex.Value))); } else { return(HoleCards.NoHolecards(playerName)); } } catch (Exception ex) { throw new CardException(handText, "ParseHoleCards: Exception " + ex.Message); } }
protected override PlayerList ParsePlayers(string[] handLines) { XDocument document = GetXDocumentFromLines(handLines); XElement gameElement = GetGameElementFromXDocument(document); XElement players = gameElement.Element("players"); PlayerList playerList = new PlayerList(); //Build a query for all cards elements which are "SHOWN" or "MUCKED" rather than "COMMUNITY" IEnumerable <XElement> cardElements = gameElement.Elements("round").Elements("cards").Where(element => element.Attribute("type").Value[0] != 'C').ToList(); foreach (XElement playerElement in players.Elements()) { //Player Element looks like: //<player seat="0" nickname="GODEXISTSJK" balance="$269.96" dealtin="true" /> decimal stack = decimal.Parse(playerElement.Attribute("balance").Value.Substring(1), System.Globalization.CultureInfo.InvariantCulture); string playerName = playerElement.Attribute("nickname").Value; int seat = Int32.Parse(playerElement.Attribute("seat").Value); Player player = new Player(playerName, stack, seat); bool dealtIn = bool.Parse(playerElement.Attribute("dealtin").Value); player.IsSittingOut = !dealtIn; //<cards type="SHOWN" cards="Ac,4c" player="7"/> XElement playerCardElement = cardElements.FirstOrDefault(card => Int32.Parse(card.Attribute("player").Value) == seat); if (playerCardElement != null) { string cardString = playerCardElement.Attribute("cards").Value; player.HoleCards = HoleCards.NoHolecards(); player.HoleCards.AddCards(BoardCards.Parse(cardString)); } playerList.Add(player); } return(playerList); }
private void ParseDealtHand(string[] handLines, int currentLine, Player player) { const int maxCards = 4; for (int i = 1; i <= maxCards; i++) { string Line = handLines[currentLine + i]; if (Line[1] != 'C') { break; } Card parsedCard = ParseCard(Line); if (!parsedCard.isEmpty) { if (player.HoleCards == null) { player.HoleCards = HoleCards.NoHolecards(); } player.HoleCards.AddCard(parsedCard); } } }
protected override PlayerList ParsePlayers(string[] handLines) { int currentLine = 1; PlayerList plist = new PlayerList(); //Parsing playerlist for (int i = 0; i < 10; i++) { //<PLAYER NAME="fatima1975" SEAT="6" AMOUNT="4.27"></PLAYER> string Line = handLines[i + 1]; if (Line[1] != 'P') { currentLine = i + 1; break; } const int playerNameStartIndex = 14; int playerNameEndIndex = Line.IndexOf('\"', playerNameStartIndex); string playerName = Line.Substring(playerNameStartIndex, playerNameEndIndex - playerNameStartIndex); if (playerName == "UNKNOWN") { continue; } int seatStartIndex = playerNameEndIndex + 8; int seatEndIndex = Line.IndexOf('\"', seatStartIndex); int seatNumber = int.Parse(Line.Substring(seatStartIndex, seatEndIndex - seatStartIndex)); int stackStartIndex = seatEndIndex + 10; int stackEndIndex = Line.IndexOf('\"', stackStartIndex); decimal stack = decimal.Parse(Line.Substring(stackStartIndex, stackEndIndex - stackStartIndex), CultureInfo.InvariantCulture); plist.Add(new Player(playerName, stack, seatNumber)); } //Parsing dealt cards for (int i = currentLine; i < handLines.Length; i++) { string Line = handLines[i]; char firstChar = Line[1]; if (firstChar == 'A') { //<ACTION TYPE="HAND_BLINDS" PLAYER="ItalyToast" KIND="HAND_BB" VALUE="200.00"></ACTION> //<ACTION TYPE="HAND_DEAL" PLAYER="AllinAnna"> const int actionTypeCharIndex = 19; char actionTypeChar = Line[actionTypeCharIndex]; if (actionTypeChar == 'D') { string playerName = GetXMLAttributeValue(Line, "PLAYER"); ParseDealtHand(handLines, i, plist[playerName]); } } if (firstChar == 'S') { currentLine = i + 1; break; } } //Parse Showdown cards for (int i = handLines.Length - 1; i > currentLine; i--) { string Line = handLines[i]; char firstChar = Line[1]; if (firstChar == 'C') { continue; } //<RESULT PLAYER="ItalyToast" WIN="10.00" HAND="$(STR_BY_DEFAULT)" WINCARDS="14 1 50 5 14 "> if (firstChar == 'R') { const int playerNameStartIndex = 16; int playerNameEndIndex = Line.IndexOf('\"', playerNameStartIndex); string playerName = Line.Substring(playerNameStartIndex, playerNameEndIndex - playerNameStartIndex); Player player = plist[playerName]; if (!player.hasHoleCards) { for (int cardIndex = i + 1; cardIndex <= i + 4 && cardIndex < handLines.Length; cardIndex++) { string cardLine = handLines[cardIndex]; if (cardLine[1] != 'C') { break; } Card parsedCard = ParseCard(cardLine); if (!parsedCard.isEmpty) { if (player.HoleCards == null) { player.HoleCards = HoleCards.NoHolecards(); } player.HoleCards.AddCard(parsedCard); } } } } if (firstChar == 'S') { break; } } return(plist); }
protected override PlayerList ParsePlayers(string[] handLines) { //Expected Start //Game started at: 2014/2/28 15:59:51 //Game ID: 258592968 2/4 Gabilite (JP) - CAP - Max - 2 (Hold'em) //Seat 4 is the button //Seat 1: xx59704 (159.21). //Seat 4: Xavier2500 (110.40). //... PlayerList playerList = new PlayerList(); int CurrentLineIndex = 3; //The first line after the player list always starts with "Player " while (handLines[CurrentLineIndex][0] == 'S') { string playerLine = handLines[CurrentLineIndex++]; const int seatNumberStart = 5; int colonIndex = playerLine.IndexOf(':', seatNumberStart + 1); int SeatNumber = int.Parse(playerLine.Substring(seatNumberStart, colonIndex - seatNumberStart)); //Parsing playerName //PlayerName can contain '(' & ')' int NameStartIndex = colonIndex + 2; int NameEndIndex = playerLine.LastIndexOfFast(" ("); string playerName = playerLine.Substring(NameStartIndex, NameEndIndex - NameStartIndex); int stackSizeStartIndex = NameEndIndex + 2; int stackSizeEndIndex = playerLine.Length - 2; string stack = playerLine.Substring(stackSizeStartIndex, stackSizeEndIndex - stackSizeStartIndex); //string playerName = playerLine.Substring(NameStartIndex, stackSizeStartIndex - NameStartIndex - 2); playerList.Add(new Player(playerName, decimal.Parse(stack, System.Globalization.CultureInfo.InvariantCulture), SeatNumber)); } //HandHistory format: //... //Player NoahSDsDad has small blind (2) //Player xx45809 sitting out //Player megadouche sitting out //Player xx59704 wait BB //Parsing Sitouts and HoleCards for (int i = CurrentLineIndex; i < handLines.Length; i++) { const int NameStartIndex = 7; string line = handLines[i]; bool receivingCards = false; int NameEndIndex; string playerName; //Uncalled bet (20) returned to zz7 if (line[0] == 'U') { break; } switch (line[line.Length - 1]) { //Player bubblebubble received card: [2h] case ']': receivingCards = true; break; case '.': //Player bubblebubble is timed out. if (line[line.Length - 2] == 't') { continue; } receivingCards = true; break; case ')': continue; case 'B': //Player bubblebubble wait BB NameEndIndex = line.Length - 8; //" wait BB".Length playerName = line.Substring(NameStartIndex, NameEndIndex - NameStartIndex); playerList[playerName].IsSittingOut = true; break; case 't': //Player xx45809 sitting out if (line[line.Length - 2] == 'u') { NameEndIndex = line.Length - 12; //" sitting out".Length playerName = line.Substring(NameStartIndex, NameEndIndex - NameStartIndex); if (playerName == "") //"Player sitting out" { continue; } playerList[playerName].IsSittingOut = true; break; } //Player TheKunttzz posts (0.25) as a dead bet else { continue; } default: throw new ArgumentException("Unhandled Line: " + line); } if (receivingCards) { CurrentLineIndex = i; break; } } //Parse HoleCards for (int i = CurrentLineIndex; i < handLines.Length; i++) { const int NameStartIndex = 7; string line = handLines[i]; char endChar = line[line.Length - 1]; if (endChar == '.') { continue; } else if (endChar == ']') { int NameEndIndex = line.LastIndexOfFast(" rec", line.Length - 12); string playerName = line.Substring(NameStartIndex, NameEndIndex - NameStartIndex); char rank = line[line.Length - 3]; char suit = line[line.Length - 2]; var player = playerList[playerName]; if (!player.hasHoleCards) { player.HoleCards = HoleCards.NoHolecards(); } if (rank == '0') { rank = 'T'; } player.HoleCards.AddCard(new Card(rank, suit)); continue; } else { break; } } //Expected End //*Player xx59704 shows: Straight to 8 [7s 4h]. Bets: 110.40. Collects: 220.30. Wins: 109.90. //Player Xavier2500 shows: Two pairs. Js and 8s [10h 8c]. Bets: 110.40. Collects: 0. Loses: 110.40. //Game ended at: for (int i = handLines.Length - playerList.Count - 1; i < handLines.Length - 1; i++) { const int WinningStartOffset = 1; const int PlayerMinLength = 7; // = "Player ".Length string summaryLine = handLines[i]; int playerNameStartIndex = PlayerMinLength + (summaryLine[0] == '*' ? WinningStartOffset : 0); int playerNameEndIndex = summaryLine.IndexOf(' ', playerNameStartIndex); int ShowIndex = summaryLine.IndexOfFast(" shows: "); if (ShowIndex != -1) { string playerName = summaryLine.Substring(playerNameStartIndex, ShowIndex - playerNameStartIndex); int pocketStartIndex = summaryLine.IndexOf('[', playerNameEndIndex) + 1; int pocketEndIndex = summaryLine.IndexOf(']', pocketStartIndex); Player showdownPlayer = playerList[playerName]; if (!showdownPlayer.hasHoleCards) { string cards = summaryLine.Substring(pocketStartIndex, pocketEndIndex - pocketStartIndex); cards = cards.Replace("10", "T"); showdownPlayer.HoleCards = HoleCards.FromCards(cards); } } } return(playerList); }
protected override PlayerList ParsePlayers(string[] handLines) { /* * <player seat="3" name="RodriDiaz3" chips="$2.25" dealer="0" win="$0" bet="$0.08" rebuy="0" addon="0" /> * <player seat="8" name="Kristi48ru" chips="$6.43" dealer="1" win="$0.23" bet="$0.16" rebuy="0" addon="0" /> * or * <player seat="5" name="player5" chips="$100000" dealer="0" win="$0" bet="$0" /> */ string[] playerLines = GetPlayerLinesFromHandLines(handLines); PlayerList playerList = new PlayerList(); for (int i = 0; i < playerLines.Length; i++) { string playerName = GetNameFromPlayerLine(playerLines[i]); decimal stack = GetStackFromPlayerLine(playerLines[i]); int seat = GetSeatNumberFromPlayerLine(playerLines[i]); playerList.Add(new Player(playerName, stack, seat) { IsSittingOut = true }); } XDocument xDocument = GetXDocumentFromLines(handLines); List <XElement> actionElements = xDocument.Element("root").Element("session").Element("game").Elements("round").Elements("action"). ToList(); foreach (Player player in playerList) { List <XElement> playerActions = actionElements.Where(action => action.Attribute("player").Value.Equals(player.PlayerName)).ToList(); if (playerActions.Count == 0) { //Players are marked as sitting out by default, we don't need to update continue; } //Sometimes the first and only action for a player is to sit out - we should still treat them as sitting out bool playerSitsOutAsAction = playerActions[0].Attribute("type").Value == "8"; if (playerSitsOutAsAction) { continue; } player.IsSittingOut = false; } /* * Grab known hole cards for players and add them to the player * <cards type="Pocket" player="pepealas5">CA CK</cards> */ string[] cardLines = GetCardLinesFromHandLines(handLines); for (int i = 0; i < cardLines.Length; i++) { string handLine = cardLines[i]; handLine = handLine.TrimStart(); //To make sure we know the exact character location of each card, turn 10s into Ts (these are recognized by our parser) //Had to change this to specific cases so we didn't accidentally change player names handLine = handLine.Replace("10 ", "T "); handLine = handLine.Replace("10<", "T<"); //We only care about Pocket Cards if (handLine[13] != 'P') { continue; } //When players fold, we see a line: //<cards type="Pocket" player="pepealas5">X X</cards> //or: //<cards type="Pocket" player="playername"></cards> //We skip these lines if (handLine[handLine.Length - 9] == 'X' || handLine[handLine.Length - 9] == '>') { continue; } int playerNameStartIndex = 29; int playerNameEndIndex = handLine.IndexOf('"', playerNameStartIndex) - 1; string playerName = handLine.Substring(playerNameStartIndex, playerNameEndIndex - playerNameStartIndex + 1); Player player = playerList.First(p => p.PlayerName.Equals(playerName)); int playerCardsStartIndex = playerNameEndIndex + 3; int playerCardsEndIndex = handLine.Length - 9; string playerCardString = handLine.Substring(playerCardsStartIndex, playerCardsEndIndex - playerCardsStartIndex + 1); string[] cards = playerCardString.Split(' '); if (cards.Length > 1) { player.HoleCards = HoleCards.NoHolecards(player.PlayerName); foreach (string card in cards) { //Suit and rank are reversed in these strings, so we flip them around before adding player.HoleCards.AddCard(new Card(card[1], card[0])); } } } return(playerList); }
protected override PlayerList ParsePlayers(string[] handLines) { int currentLine = 1; PlayerList plist = new PlayerList(); //Parsing playerlist for (int i = 0; i < 10; i++) { //<PLAYER NAME="fatima1975" SEAT="6" AMOUNT="4.27"></PLAYER> string Line = handLines[i + 1]; if (Line[1] != 'P') { currentLine = i + 1; break; } const int playerNameStartIndex = 14; int playerNameEndIndex = Line.IndexOf('\"', playerNameStartIndex); string playerName = Line.Substring(playerNameStartIndex, playerNameEndIndex - playerNameStartIndex); playerName = WebUtility.HtmlDecode(playerName); if (playerName == "UNKNOWN" || playerName == "") { continue; } int seatStartIndex = playerNameEndIndex + 8; int seatEndIndex = Line.IndexOf('\"', seatStartIndex); int seatNumber = FastInt.Parse(Line, seatStartIndex); int stackStartIndex = seatEndIndex + 10; int stackEndIndex = Line.IndexOf('\"', stackStartIndex); decimal stack = decimal.Parse(Line.Substring(stackStartIndex, stackEndIndex - stackStartIndex), provider); var state = GetXMLAttributeValue(Line, "STATE"); bool sitout = IsSitOutState(state); plist.Add(new Player(playerName, stack, seatNumber) { IsSittingOut = sitout }); } //Parsing dealt cards for (int i = currentLine; i < handLines.Length; i++) { string Line = handLines[i]; char firstChar = Line[1]; if (firstChar == 'A') { //<ACTION TYPE="HAND_BLINDS" PLAYER="ItalyToast" KIND="HAND_BB" VALUE="200.00"></ACTION> //<ACTION TYPE="HAND_DEAL" PLAYER="AllinAnna"> const int actionTypeCharIndex = 19; char actionTypeChar = Line[actionTypeCharIndex]; if (actionTypeChar == 'D') { string playerName = GetPlayerXMLAttributeValue(Line); ParseDealtHand(handLines, i, plist[playerName]); } } if (firstChar == 'S') { currentLine = i + 1; break; } } //Parse Showdown cards int showDownIndex = GetShowdownStartIndex(handLines); if (showDownIndex != -1) { Player currentPlayer = null; for (int i = showDownIndex; i < handLines.Length; i++) { string Line = handLines[i]; char firstChar = Line[1]; //<SHOWDOWN NAME="HAND_SHOWDOWN" POT="895.02" RAKE="15.00" MAINPOT="895.02" LEFTPOT="" RIGHTPOT="" STARTING="Player4"> //<RESULT PLAYER="Player4" WIN="0.00" HAND="$(STR_G_WIN_PAIR) $(STR_G_CARDS_DEUCES)" WINCARDS="40 1 0 9 45 "> //<CARD LINK="46"></CARD> //<CARD LINK="1"></CARD> //<CARD LINK="9"></CARD> //<CARD LINK="47"></CARD></RESULT> if (firstChar == 'R') { string playerName = GetPlayerXMLAttributeValue(Line); var player = plist[playerName]; if (!player.hasHoleCards) { currentPlayer = player; } else { currentPlayer = null; } continue; } //<CARD LINK="9"></CARD> if (firstChar == 'C' && currentPlayer != null) { Card?parsedCard = ParseCard(Line); if (parsedCard.HasValue) { if (currentPlayer.HoleCards == null) { currentPlayer.HoleCards = HoleCards.NoHolecards(); } currentPlayer.HoleCards.AddCard(parsedCard.Value); } } } } return(plist); }
protected override PlayerList ParsePlayers(string[] handLines) { /* * <player seat="3" name="RodriDiaz3" chips="$2.25" dealer="0" win="$0" bet="$0.08" rebuy="0" addon="0" /> * <player seat="8" name="Kristi48ru" chips="$6.43" dealer="1" win="$0.23" bet="$0.16" rebuy="0" addon="0" /> * or * <player seat="5" name="player5" chips="$100000" dealer="0" win="$0" bet="$0" /> */ List <string> playerLines = GetPlayerLinesFromHandLines(handLines); PlayerList playerList = new PlayerList(); for (int i = 0; i < playerLines.Count; i++) { string playerName = GetNameFromPlayerLine(playerLines[i]); decimal stack = GetStackFromPlayerLine(playerLines[i]); int seat = GetSeatNumberFromPlayerLine(playerLines[i]); playerList.Add(new Player(playerName, stack, seat) { IsSittingOut = true }); } var actionLines = handLines.Where(p => p.StartsWithFast("<act")); foreach (var line in actionLines) { string player = GetPlayerFromActionLine(line); int type = GetActionTypeFromActionLine(line); //action line may have an empty name and then we skip it //<action no="3" sum="€0" cards="" type="9" player=""/> if (type != 8 && player != "") { playerList[player].IsSittingOut = false; } } /* * Grab known hole cards for players and add them to the player * <cards type="Pocket" player="pepealas5">CA CK</cards> */ List <string> cardLines = GetCardLinesFromHandLines(handLines); for (int i = 0; i < cardLines.Count; i++) { string line = cardLines[i]; //Getting the cards Type int typeIndex = line.IndexOfFast("e=\"", 10) + 3; char typeChar = line[typeIndex]; //We only care about Pocket Cards if (typeChar != 'P') { continue; } //When players fold, we see a line: //<cards type="Pocket" player="pepealas5">X X</cards> //or: //<cards type="Pocket" player="playername"></cards> //We skip these lines if (line[line.Length - 9] == 'X' || line[line.Length - 9] == '>') { continue; } int playerNameStartIndex = line.IndexOfFast("r=\"", 10) + 3; int playerNameEndIndex = line.IndexOf('"', playerNameStartIndex) - 1; string playerName = line.Substring(playerNameStartIndex, playerNameEndIndex - playerNameStartIndex + 1); Player player = playerList.First(p => p.PlayerName.Equals(playerName)); int playerCardsStartIndex = line.LastIndexOf('>', line.Length - 11) + 1; int playerCardsEndIndex = line.Length - 9; string playerCardString = line.Substring(playerCardsStartIndex, playerCardsEndIndex - playerCardsStartIndex + 1); ////To make sure we know the exact character location of each card, turn 10s into Ts (these are recognized by our parser) ////Had to change this to specific cases so we didn't accidentally change player names playerCardString = playerCardString.Replace("10", "T"); if (playerCardString.Length > 1) { player.HoleCards = HoleCards.NoHolecards(); for (int j = 0; j < playerCardString.Length; j += 3) { char suit = playerCardString[j]; char rank = playerCardString[j + 1]; player.HoleCards.AddCard(new Card(rank, suit)); } } } return(playerList); }