/// <summary>
        /// Runs a play test simulation of the saved agent and returns the result.
        /// </summary>
        /// <param name="savedAgent"></param>
        /// <param name="testType"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public PlaytestResult RunSimulation(SavedAgent savedAgent, TestType testType, bool record)
        {
            int               action                    = 0;
            int               movesTotal                = 0;
            int               currentScore              = 0;
            int               movesSincePoint           = 0;
            int               maxStepsBeforeTerminating = 1000;
            double            averageMovesPerFood       = 0;
            bool              isInBounds                = true;
            PlaytestRecording recorder                  = null;
            TestResult        testResult                = TestResult.Failed;

            NetworkSettings networkSettings = (savedAgent.geneticSettings.FitnessCalculator as SnakeFitnessCalculator).NetworkSettings;
            SnakeSettings   snakeSettings   = (savedAgent.geneticSettings.FitnessCalculator as SnakeFitnessCalculator).SnakeSettings;

            // Setup new snake game and neural network
            NeuralNetwork neuralNetwork = new NeuralNetwork(networkSettings, savedAgent.agent.Chromosome.ToArray());

            double[]  input     = new double[networkSettings.numberOfInputNeurons];
            SnakeGame snakeGame = new SnakeGame(snakeLevel);

            // Make recorder
            if (record)
            {
                recorder = new PlaytestRecording(savedAgent.agent, networkSettings, snakeSettings);
                recorder.TakeSnapShotInitial(snakeGame);
            }

            if (record) // Save round info.
            {
                recorder.TakeSnapShotRound(snakeGame);
            }

            // Check within bounds.
            if (testType == TestType.WithinBounds)
            {
                if (snakeGame.Grid.PointWithinGrid(snakeGame.Snake.Head.Point))
                {
                    testResult = TestResult.Passed;
                }
                else
                {
                    testResult = TestResult.Failed;
                    isInBounds = false;
                }
            }

            if (isInBounds)
            {
                do
                {
                    input  = ConvertGridToInput(snakeGame.Grid, snakeGame.Snake, snakeGame.Food);
                    action = neuralNetwork.CalculateOutput(input);
                    snakeGame.UpdateDirection(action);

                    // Check if got point
                    if (snakeGame.Score != currentScore)
                    {
                        movesSincePoint = 0;
                        currentScore    = snakeGame.Score;
                    }
                    else
                    {
                        movesSincePoint++;
                    }
                    movesTotal++;

                    if (record) // Save round info.
                    {
                        recorder.TakeSnapShotRound(snakeGame);
                    }
                    // Test within bounds.
                    if (testType == TestType.WithinBounds)
                    {
                        if (snakeGame.Grid.PointWithinGrid(snakeGame.Snake.Head.Point))
                        {
                            testResult = TestResult.Passed;
                        }
                        else
                        {
                            testResult = TestResult.Failed;
                            isInBounds = false;
                        }
                    }
                } while(snakeGame.Snake.IsAlive && movesSincePoint < maxStepsBeforeTerminating && isInBounds);
            }

            // Check if snake completed game.
            if (testType == TestType.CanComplete)
            {
                if (snakeGame.MaxScore != snakeGame.Score)
                {
                    testResult = TestResult.Failed;
                }
                else
                {
                    testResult = TestResult.Passed;
                }
            }

            // Get avg. moves per food.
            if (snakeGame.FoodEaten != 0)
            {
                averageMovesPerFood = movesTotal / (double)snakeGame.FoodEaten;
            }
            EndTestInfo endTestInfo = new EndTestInfo(snakeGame, movesTotal);

            if (record)
            {
                recorder.TakeSnapShotEndTest(endTestInfo);
            }

            PlaytestResult playtestResult = new PlaytestResult(testResult, recorder);

            return(playtestResult);
        }
示例#2
0
 /// <summary>
 /// Saves information about the snake game after the simulation round has ended.
 /// </summary>
 /// <param name="snakeGame"></param>
 public void TakeSnapShotEndTest(EndTestInfo endTestInfo)
 {
     EndTestInfo = endTestInfo;
 }