예제 #1
0
        public void RunGameWithoutHuman()
        {
            var game = _GameCreationDelegate(_settings[_currentGameNumber], GamePurpose.fastGameInBackgroundWithoutVisualization);

            game.roundNumber = -1;
            game.rounds      = new List <TRound>();

            int runtimeErrorOrTimeLimitCounter = 0;

            while (!game.GameFinished && GameForm.UserWantsToClose == false)
            {
                game.roundNumber++;
                var round = new TRound();
                round.random = new System.Random(Rand.Next());
                round.turns  = new List <TTurn>();

                game.PreparationsBeforeRound();
                List <TPlayer> order    = game.GetTurnOrderForNextRound();
                bool           addRound = true;
                while (round.turns.Count < order.Count)
                {
                    TPlayer player = order[round.turns.Count];
                    ExternalProgramExecuter epe =
                        new ExternalProgramExecuter(player.programAddress, "input.txt", "output.txt", _settings[_currentGameNumber].JavaPath, _settings[_currentGameNumber].PythonPath);


                    string input = game.GetInputFile(player);
                    string output;
                    string comment;

                    ExecuteResult res = epe.Execute(input, FrameworkSettings.ExecutionTimeLimitSeconds, out output, out comment);

                    var turn = game.GetProgramTurn(player, output, res, ExternalProgramExecuter.ExecuteResultToString(res));
                    turn.output = output; //todo this is bad
                    turn.input  = input;
                    round.turns.Add(turn);

                    if (res == ExecuteResult.InternalError || res == ExecuteResult.NotStarted || res == ExecuteResult.TimeOut)
                    {
                        runtimeErrorOrTimeLimitCounter++;
                    }
                    if (runtimeErrorOrTimeLimitCounter == 2)
                    {
                        //todo test game stipping
                        var dialogResult = _gameForm.ThreadSafeMessageBox("Остановка игры", "Вызов программы дважды завершился с ошибкой. YES = остановить игру, NO = продолжить до двух новых ошибочных запусков, CANCEL = продолжить до двадцати новых ошибочных запусков", MessageBoxButtons.YesNoCancel);
                        if (dialogResult == DialogResult.Yes)
                        {
                            game.GameFinished = true;
                            addRound          = false;
                            break;
                        }
                        else if (dialogResult == DialogResult.No)
                        {
                            runtimeErrorOrTimeLimitCounter = 0;
                        }
                        else
                        {
                            runtimeErrorOrTimeLimitCounter = -18;
                        }
                    }
                }
                if (addRound)
                {
                    game.rounds.Add(round);
                    _allRounds.TryAdd(game.roundNumber, round);
                    game.ProcessRoundAndSetTotalStage(round);
                }
            }

            if (_settings[_currentGameNumber].SaveReplays)
            {
                var path = _settings[_currentGameNumber].ReplayFolder + "\\" + _settings[_currentGameNumber].ReplayFileName;
                try
                {
                    var replay = new Replay
                    {
                        AllRounds           = _allRounds.Values.ToList(),
                        ParamsFromStartForm = _settings[_currentGameNumber]
                    };
                    Serialize.TryWriteToXmlFile(path, replay);
                }
                catch
                {
                    if (Debugger.IsAttached)
                    {
                        throw;
                    }
                }
            }

            GameForm.GameInBackgroundRunning = false;
        }
예제 #2
0
        public Frame Process(GlInput input)
        {
            if (input.KeyTime(System.Windows.Input.Key.Escape) == 1)
            {
                return(null);
            }
            if (GameForm.UserWantsToClose && !GameForm.GameInBackgroundRunning)
            {
                return(null);
            }
            if (input.KeyTime(System.Windows.Input.Key.P) == 1)
            {
                PauseButtonPressed   = !PauseButtonPressed;
                _gameForm.GamePaused = PauseButtonPressed;
            }
            else
            {
                PauseButtonPressed = _gameForm.GamePaused;
            }

            _gameForm.UserWantsPauseAfterTurn |= input.KeyTime(System.Windows.Input.Key.Oem4) == 1;//кнопка открытая квадратная скобка, или русская буква х

            bool goToBeforeRoundAfterDrawing = false;

            if (!PauseButtonPressed)
            {
                //фазы лесенкой, чтобы можно было хоть по всем пройтись

                if (_processPhase == EProcessPhase.beforeRound)
                {
                    if (_game.GameFinished)
                    {
                        GoToPhase(EProcessPhase.gameFinished);
                    }
                    else
                    {
                        if (_gameMode == EGameMode.localWithHuman)
                        {
                            GoToPhase(EProcessPhase.getTurnsOfNextRound);
                        }
                        else if (_gameMode == EGameMode.localWithoutHuman || _gameMode == EGameMode.replayFile)
                        {
                            if (_allRounds.ContainsKey(_game.roundNumber))
                            {
                                _allRounds.TryGetValue(_game.roundNumber, out _currentRound);
                                GoToPhase(EProcessPhase.processRound);
                            }
                            else
                            {
                                if (_gameMode == EGameMode.replayFile)
                                {
                                    _game.GameFinished = true;
                                    GoToPhase(EProcessPhase.gameFinished);
                                }
                            }
                            //  else
                            //  {
                            //      if (_game.roundNumber > 5)
                            //      {
                            //           _gameForm.InfoAction = "Рекомендуем снизить скорость просмотра";
                            //      }
                            // }
                        }
                        //иначе остаемся крутиться в before round, пока во втором потоке не сформируется ход
                    }
                }

                if (_processPhase == EProcessPhase.getTurnsOfNextRound)
                {
                    bool humanTurnWasAdded = false;
                    while (_currentRound.turns.Count < _currentPlayerOrder.Count)
                    {
                        var player = _currentPlayerOrder[_currentRound.turns.Count];
                        if (player.controlledByHuman)
                        {
                            if (humanTurnWasAdded && FrameworkSettings.ForInnerUse.GetAllUserTurnsImmediately == false)
                            {
                                break;
                            }

                            var turn = _game.TryGetHumanTurn(player, input);
                            if (turn != null)
                            {
                                turn.input = _game.GetInputFile(player);
                                _currentRound.turns.Add(turn);
                                humanTurnWasAdded = true;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            ExternalProgramExecuter epe =
                                new ExternalProgramExecuter(player.programAddress, "input.txt", "output.txt", _settings[_currentGameNumber].JavaPath, _settings[_currentGameNumber].PythonPath);

                            string inputFile = _game.GetInputFile(player);
                            string output;
                            string comment; //exitCode, нигде не используется

                            GameForm.GameInBackgroundRunning = true;
                            ExecuteResult res = epe.Execute(inputFile, FrameworkSettings.ExecutionTimeLimitSeconds, out output, out comment);
                            GameForm.GameInBackgroundRunning = false;

                            var turn = _game.GetProgramTurn(player, output, res, ExternalProgramExecuter.ExecuteResultToString(res));
                            turn.input = inputFile;
                            _currentRound.turns.Add(turn);
                        }
                    }

                    if (_currentRound.turns.Count == _currentPlayerOrder.Count)
                    {
                        GoToPhase(EProcessPhase.processRound);
                    }
                }

                if (_processPhase == EProcessPhase.waitUntilAnimationFinished)
                {
                    UpdateAnimationStage();
                    if (animationFinished)
                    {
                        goToBeforeRoundAfterDrawing = true;
                    }
                }

                if (_processPhase == EProcessPhase.gameFinished)
                {
                    if (input.KeyTime(System.Windows.Input.Key.Enter) == 1)
                    {
                        bool success = TryInitNextGame();
                        if (!success)
                        {
                            return(null);
                        }
                    }
                }
            }

            Frame frame = new Frame();

            _game.DrawAll(frame, animationStage, animationFinishStage, _processPhase == EProcessPhase.getTurnsOfNextRound, input);
            if (_currentRound != null)
            {
                DrawAndProcessTimeline(frame, input);
            }

            if (goToBeforeRoundAfterDrawing)
            {
                GoToPhase(EProcessPhase.beforeRound);
            }

            _game.frameNumber++;



            return(frame);
        }