예제 #1
0
        /// <summary>
        /// Calculates the resulting fitness value by using the passed weights
        /// and returns the value in a FitnessInfo class together with other relevant info about the calculation.
        /// </summary>
        public IFitnessInfo CalculateFitness(double[] weightsForNeuralNetwork)
        {
            int    action              = 0;
            int    currentScore        = 0;
            int    movesSincePoint     = 0;
            int    movesTotal          = 0;
            double fitness             = 0;
            double averageMovesPerFood = 0;

            double[]    input = new double[ProgramSettings.NUMBER_OF_INPUT_NEURONS];
            EndGameInfo endGameInfo;

            // Setup new snake game and neural network
            neuralNetwork = new NeuralNetwork(NetworkSettings, weightsForNeuralNetwork);
            snakeGame     = new SnakeGame(SnakeSettings);

            // Make recorder
            if (record)
            {
                recorder = new FitnessCalculatorRecording(agentToRecord, NetworkSettings, SnakeSettings);
                recorder.TakeSnapShotInitial(snakeGame, movesSincePoint, movesTotal, input, neuralNetwork);
            }

            // Simulation begins
            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, movesSincePoint, movesTotal, input, neuralNetwork);
                }
                FitnessRoundsCount++;
            } while(snakeGame.Snake.IsAlive && movesSincePoint < GetMaxMoves(snakeGame.Snake.Lenght));

            if (snakeGame.FoodEaten != 0)
            {
                averageMovesPerFood = movesTotal / (double)snakeGame.FoodEaten;
            }

            fitness     = snakeGame.Score;
            endGameInfo = new EndGameInfo(snakeGame, fitness, averageMovesPerFood, movesTotal);

            if (record)
            {
                recorder.TakeSnapShotEndGame(endGameInfo);
            }
            return(endGameInfo);
        }
예제 #2
0
 /// <summary>
 /// Saves information after the fitness calculation has ended.
 /// </summary>
 /// <param name="newEndGameInfo"></param>
 public void TakeSnapShotEndGame(EndGameInfo newEndGameInfo)
 {
     this.newEndGameInfo = newEndGameInfo;
 }