/// <summary> /// Create from game string. /// GameDefinition is optional and allows to set some properties (e.g. CurrentActor) correctly. /// </summary> public GameState(string gameString, GameDefinition gameDef) { string error; GameRecord gameRecord = GameRecord.Parse(gameString, out error); if (gameRecord == null) { throw new ApplicationException("Cannot create GameState: " + error); } InitializeFromGameRecord(gameRecord, gameDef); }
private void InitializeFromGameRecord(GameRecord gameRecord, GameDefinition gameDef) { Initialize(gameDef, gameRecord.Players.Count); Id = gameRecord.Id; Bet = 0; for (int p = 0; p < Players.Length; ++p) { Players[p].Name = gameRecord.Players[p].Name; Players[p].Stack = gameRecord.Players[p].Stack; Players[p].PutAmountInPot(gameRecord.Players[p].Blind); Pot += gameRecord.Players[p].Blind; if (Bet < gameRecord.Players[p].Blind) { Bet = gameRecord.Players[p].Blind; } } if (Bet > 0) { BetCount = 1; } // Set initial actor CurrentActor = DealerPosition; IsDealerActing = true; for (int a = 0; a < gameRecord.Actions.Count; ++a) { UpdateByAction(gameRecord.Actions[a], gameDef); } IsGameOver = gameRecord.IsGameOver; for (int p = 0; p < Players.Length; ++p) { Players[p].Result = gameRecord.Players[p].Result; } if (IsGameOver) { for (int p = 0; p < Players.Length; ++p) { Players[p].Stack = gameRecord.Players[p].Stack + gameRecord.Players[p].Result; } } }
internal static bool Parse(string gameString, out string error, GameRecord gameRecord) { try { if (String.IsNullOrEmpty(gameString)) { return(Error(out error, "Empty game log")); } error = ""; int curPos = 0; int playerCount = 0; if (!ReadGameId(gameString, ref curPos, gameRecord, ref error)) { return(false); } if (!ReadPlayers(gameString, ref curPos, gameRecord, ref error, ref playerCount)) { return(false); } char terminator; if (!ParseActions(gameString, curPos, playerCount, gameRecord.Actions, ref error, out terminator)) { return(false); } if (terminator == '?') { return(Error(out error, "No game string terminator found.")); } gameRecord.IsGameOver = terminator == '.'; return(true); } catch (Exception e) { error = e.ToString(); } return(false); }
private static bool ReadGameId(string gameString, ref int curPos, GameRecord gameRecord, ref string error) { curPos = SkipWhiteSpace(gameString, curPos); int nextPos; for (nextPos = curPos; nextPos < gameString.Length; ++nextPos) { switch (gameString[nextPos]) { case ';': goto gameIdSeparatorFound; } } return(Error(out error, "Game Id not found")); gameIdSeparatorFound: gameRecord.Id = gameString.Substring(curPos, nextPos - curPos); curPos = nextPos + 1; return(true); }
private static bool ReadPlayers(string gameString, ref int curPos, GameRecord gameRecord, ref string error, ref int playerCount) { for (; curPos < gameString.Length;) { curPos = SkipWhiteSpace(gameString, curPos); int nextPos; for (nextPos = curPos; nextPos < gameString.Length; ++nextPos) { switch (gameString[nextPos]) { case '{': goto leftBraceFound; case ';': curPos++; return(true); } } return(Error(out error, "{ after player name not found")); leftBraceFound: GameRecord.Player parsedPlayer = new GameRecord.Player(); parsedPlayer.Name = gameString.Substring(curPos, nextPos - curPos); curPos = nextPos + 1; double amount; bool amountFound; curPos = SkipWhiteSpace(gameString, curPos); if (!ReadAmount(gameString, ref curPos, ref error, out amountFound, out amount)) { return(false); } if (!amountFound) { return(Error(out error, "No stack amount found")); } parsedPlayer.Stack = amount; curPos = SkipWhiteSpace(gameString, curPos); if (!ReadAmount(gameString, ref curPos, ref error, out amountFound, out amount)) { return(false); } if (!amountFound) { return(Error(out error, "No blind amount found")); } parsedPlayer.Blind = amount; curPos = SkipWhiteSpace(gameString, curPos); if (!ReadAmount(gameString, ref curPos, ref error, out amountFound, out amount)) { return(false); } if (!amountFound) { return(Error(out error, "No result amount found")); } parsedPlayer.Result = amount; gameRecord.Players.Add(parsedPlayer); playerCount++; for (; curPos < gameString.Length; ++curPos) { if (gameString[curPos] == '}') { goto rightBraceFound; } } return(Error(out error, "} after player name not found")); rightBraceFound: curPos++; } return(Error(out error, "Players terminator not found")); }
public static GameRecord Parse(string gameString, out string error) { GameRecord gr = new GameRecord(); return(GameStringParser.Parse(gameString, out error, gr) ? gr : null); }
/// <summary> /// Create from game record. /// GameDefinition is optional and allows to set some properties (e.g. CurrentActor) correctly. /// </summary> public GameState(GameRecord gameRecord, GameDefinition gameDef) { InitializeFromGameRecord(gameRecord, gameDef); }
/// <summary> /// Parses a file from a given position. /// </summary> public void ParseFile(string file, long startPosition) { if (!_reIncludeFiles.IsMatch(file)) { if (Verbose) { Console.WriteLine("Skip file: {0}", file); } return; } if (Verbose) { Console.WriteLine("Opening game log file: {0}", file); } FilesCount++; CurrentFile = file; CurrentLine = 0; using (FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { stream.Seek(startPosition, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(stream)) { while (!sr.EndOfStream) { CurrentLine++; string gameString = sr.ReadLine(); if (_reEmptyLine.IsMatch(gameString)) { continue; } if (gameString.Length > 0) { switch (gameString[0]) { case COMMENT_CHAR: continue; case META_DATA_CHAR: if (OnMetaData != null) { OnMetaData(this, gameString.Substring(1)); } continue; } } string error = "unknown error"; GameRecord gameRecord = GameRecord.Parse(gameString, out error); if (gameRecord == null) { ProcessError(error); } else { GamesCount++; if (OnGameRecord != null) { OnGameRecord(this, gameRecord); } } } LastFilePosition = stream.Position; } } }