public Point GetOutput(int turn)
        {
            Point result;

            if (_replayData.OutputLines.Count <= turn + 1)
            {
                return(Point.Zero);
            }

            if (!ReplayMatchData.TryParsePoint(_replayData.OutputLines[turn + 1], out result))
            {
                return(Point.Zero);
            }
            return(result);
        }
        private GameMain(GameConfig gameConfig, ReplayMatchData replayData, Logger gameLogger,
                         AiLogger[] aiLoggers, bool isPersistent, IServiceProvider serviceProvider,
                         MonoGameControl gameControl, GraphicsDevice graphicsDevice, bool isBuildingCaches, SpecialRand fixeRandom = null)
        {
            IsPersistent     = isPersistent;
            GameLogger       = gameLogger;
            IsBuildingCaches = isBuildingCaches;

            if (Content == null)
            {
                Content = new ContentManager(serviceProvider, "Content");
            }

            _spriteBatch = new SpriteBatch(graphicsDevice);
            _camera      = new Camera(graphicsDevice);

            GameConfig  = gameConfig;
            FixedRandom = fixeRandom ?? new SpecialRand((uint)GameConfig.RandomSeed);

            _fields = new Field[2];

            var replayPlayerData = new[]
            { replayData.Player1ReplayData, replayData.Player2ReplayData };

            for (var i = 0; i < 2; ++i)
            {
                var tx = 50 * (i + 1) + 325 * i;
                var ty = 100;

                if (IsPersistent)
                {
                    _fields[i] = new PersistentField(tx, ty, GameConfig, aiLoggers[i], this,
                                                     _spriteBatch, _camera, gameControl, replayPlayerData[i]);
                }
                else
                {
                    _fields[i] = new Field(tx, ty, GameConfig, aiLoggers[i], this, _spriteBatch,
                                           _camera, gameControl, replayPlayerData[i]);
                }

                _fields[i].Index = i;
            }
            _fields[0].OtherField = _fields[1];
            _fields[1].OtherField = _fields[0];

            CurrentTurn = TurnEnum.None;
        }
        public void Load(string fileName)
        {
            using (var reader = new StreamReader(fileName)) {
                int matchesCount;
                if (!int.TryParse(reader.ReadLine().Trim(), out matchesCount))
                {
                    throw new InvalidDataException(fileName);
                }

                for (var i = 0; i < matchesCount; ++i)
                {
                    var match = new ReplayMatchData();
                    match.ReadFromStreamReader(reader);
                    Matches.Add(match);
                }
            }
        }
        public static GameMain Run(GameConfig gameConfig, ReplayMatchData replayData,
                                   Logger gameLogger, AiLogger[] aiLoggers, bool isPersistent,
                                   IServiceProvider serviceProvider, MonoGameControl gameControl,
                                   GraphicsDevice graphicsDevice, bool isBuildingCaches, SpecialRand fixedRandom = null)
        {
            var gameMain = new GameMain(gameConfig, replayData, gameLogger, aiLoggers, isPersistent,
                                        serviceProvider, gameControl, graphicsDevice, isBuildingCaches, fixedRandom);

            gameMain.LaodContent();

            foreach (var field in gameMain._fields)
            {
                field.InitializeGame();
            }
            gameMain._stopwatch.Start();

            return(gameMain);
        }
        public override void StartTurn()
        {
            IsRunning = true;
            OutPut    = Point.Zero;
            if (CurrentHead < _replayData.OutputLines.Count)
            {
                Point result;
                var   aiLogger = CurrentField.AiLogger;
                aiLogger.InputLogger.WriteLine(CurrentField.GenerateTurnInfoString());
                aiLogger.OutputLogger.WriteLine(_replayData.OutputLines[CurrentHead]);

                if (!ReplayMatchData.TryParsePoint(_replayData.OutputLines[CurrentHead], out result))
                {
                    CurrentHead = int.MaxValue;
                    IsRunning   = false;
                    return;
                }
                OutPut = result;
                CurrentHead++;
            }

            IsRunning = false;
        }
            private string Match(string player1FileName, string player2FileName, string replayPath)
            {
                var replayGameData = new ReplayGameData();
                var gameConfig     = new GameConfig(GameConfig)
                {
                    Player1WonCount = 0,
                    Player2WonCount = 0,
                    RandomSeed      = Environment.TickCount
                };

                var player1WonCount = 0;
                var player2WonCount = 0;

                var fileNames = new[]
                { player1FileName, player2FileName };

                GameMain gameMain = null;

                var flipped = false;

                for (var i = 0; (i < 4) || (player1WonCount == player2WonCount); ++i)
                {
                    fileNames[0] = flipped ? player2FileName : player1FileName;
                    fileNames[1] = flipped ? player1FileName : player2FileName;
                    gameConfig.Player1WonCount = flipped ? player2WonCount : player1WonCount;
                    gameConfig.Player2WonCount = flipped ? player1WonCount : player2WonCount;

                    var currentRandom = gameMain?.FixedRandom ??
                                        new SpecialRand((uint)gameConfig.RandomSeed);
                    gameMain?.Dispose();
                    var gameLogger = new Logger();
                    gameLogger.EnableWritingConsole = true;
                    var aiLoggers = new[] { new AiLogger(), new AiLogger() };
                    gameMain = GameMain.Run(GameConfig, fileNames, true, gameLogger, aiLoggers,
                                            new SpecialRand(currentRandom));

                    while (gameMain.CurrentState == GameMain.GameStateEnum.Running)
                    {
                        Thread.Sleep(30);
                        gameMain.Update();
                    }

                    Console.WriteLine("終わり");
                    if (gameMain.CurrentState == GameMain.GameStateEnum.Player1Won)
                    {
                        if (flipped)
                        {
                            player2WonCount++;
                        }
                        else
                        {
                            player1WonCount++;
                        }
                    }
                    else if (gameMain.CurrentState == GameMain.GameStateEnum.Player2Won)
                    {
                        if (flipped)
                        {
                            player1WonCount++;
                        }
                        else
                        {
                            player2WonCount++;
                        }
                    }

                    aiLoggers[0].WaitEvents();
                    aiLoggers[1].WaitEvents();
                    gameLogger.WaitEvent();

                    var aiPlayer1 = gameMain.GetPlayer(0) as AiPlayer;
                    var aiPlayer2 = gameMain.GetPlayer(1) as AiPlayer;

                    var player1Replay = new ReplayPlayerData {
                        LeftTimeOnLaunched = aiPlayer1.LeftTimeOnLaunched,
                        LeftThinkTimes     = aiPlayer1.LeftThinkTimes,
                        OutputLines        = aiPlayer1.AiOutputs
                    };

                    var player2Replay = new ReplayPlayerData {
                        LeftTimeOnLaunched = aiPlayer2.LeftTimeOnLaunched,
                        LeftThinkTimes     = aiPlayer2.LeftThinkTimes,
                        OutputLines        = aiPlayer2.AiOutputs
                    };

                    var match = new ReplayMatchData {
                        Player1ReplayData = player1Replay,
                        Player2ReplayData = player2Replay,
                        GameConfig        = new GameConfig(gameConfig),
                        GameRandom        = currentRandom
                    };

                    replayGameData.Matches.Add(match);

                    if (i < 4)
                    {
                        flipped = !flipped;
                    }
                    else
                    {
                        flipped = _random.Next(0, 2) == 0;
                    }

                    if ((i < 4) && (3 - i < Math.Abs(player1WonCount - player2WonCount)))
                    {
                        break;
                    }
                }

                Directory.CreateDirectory(replayPath);
                replayGameData.Save(replayPath + "replay.txt");

                return(player1WonCount < player2WonCount ? player2FileName : player1FileName);
            }