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;
        }
        public override void StartTurn()
        {
            IsRunning = true;

            var turnInfo = new StringBuilder();

            turnInfo.Append(CurrentField.GenerateTurnInfoString());
            turnInfo.Append(OtherField.GenerateTurnInfoString());

            var gameLogger = GameMain.GameLogger;
            var stopWatch  = new Stopwatch();

            stopWatch.Start();

            _inputQueue.Enqueue(turnInfo.ToString());

            var task = Task.Factory.StartNew(() => {
                gameLogger.Write("AI入力待ち->");
                int x, y;
                var aiLogger = CurrentField.AiLogger;
                var input    = _playerAi.StandardOutput.ReadLine();
                aiLogger.OutputLogger.WriteLine(input);
                AiOutputs.Add(input ?? "");

                var lines = input?.Split(' ');

                if (_token.IsCancellationRequested)
                {
                    return;
                }

                stopWatch.Stop();
                _totalThinkTime += stopWatch.Elapsed;
                LeftThinkTimes.Add(LeftMilliseconds);

                if (lines == null || lines.Length != 2 ||
                    !int.TryParse(lines[0], out x) ||
                    !int.TryParse(lines[1], out y))
                {
                    stopWatch.Stop();
                    _totalThinkTime += stopWatch.Elapsed;
                    LeftThinkTimes.Add(LeftMilliseconds);
                    OutPut = new Point();
                    Dispose();
                    gameLogger.WriteLine("AIの出力が無効 (" + stopWatch.ElapsedMilliseconds + "ms, left " +
                                         LeftMilliseconds / 1000 + "s)");
                    return;
                }

                if (TotalTimeLimit < _totalThinkTime)
                {
                    OutPut = new Point();
                    gameLogger.WriteLine("合計思考時間の時間制限超過:" + x + " " + y + " (" +
                                         stopWatch.ElapsedMilliseconds + "ms, left " +
                                         LeftMilliseconds / 1000 + "s)");
                    return;
                }
                gameLogger.WriteLine("OK:" + x + " " + y + " (" + stopWatch.ElapsedMilliseconds +
                                     "ms, left " + LeftMilliseconds / 1000 + "s)");
                OutPut = new Point(x, y);
            });

            try {
                if (!task.Wait(10000))
                {
                    gameLogger.WriteLine("1ターンの時間制限超過:" + task.Status);
                    Dispose();
                    return;
                }
            } catch (AggregateException exception)
                when(exception.InnerExceptions.Any(e => e is OperationCanceledException))
                {
                    return;
                }

            gameLogger.WriteLine("ターン終了:" + OutPut + " 入力待ちタスク:" + task.Status);
            IsRunning = false;
        }