/// <summary>
        ///     Runs the navigator through its corresponding maze and records data about said evaluation (e.g. solved status, time
        ///     steps, and trajectory).
        /// </summary>
        /// <param name="evaluationUnit">A single unit of evaluation containing a paired maze and navigator.</param>
        /// <param name="experimentParameters">Parameters that control the navigation simulation.</param>
        public static void EvaluateMazeNavigatorUnit(MazeNavigatorEvaluationUnit evaluationUnit,
                                                     ExperimentParameters experimentParameters)
        {
            // Build maze configuration
            var mazeConfiguration =
                new MazeConfiguration(DataManipulationUtil.ExtractMazeWalls(evaluationUnit.MazePhenome.Walls),
                                      DataManipulationUtil.ExtractStartEndPoint(evaluationUnit.MazePhenome.StartLocation),
                                      DataManipulationUtil.ExtractStartEndPoint(evaluationUnit.MazePhenome.TargetLocation),
                                      evaluationUnit.MazePhenome.MaxTimesteps);

            // Create trajectory behavior characterization (in order to capture full trajectory of navigator)
            IBehaviorCharacterization behaviorCharacterization = new TrajectoryBehaviorCharacterization();

            // Create the maze navigation world
            var world = new MazeNavigationWorld <BehaviorInfo>(mazeConfiguration.Walls,
                                                               mazeConfiguration.NavigatorLocation, mazeConfiguration.GoalLocation,
                                                               experimentParameters.MinSuccessDistance, mazeConfiguration.MaxSimulationTimesteps,
                                                               behaviorCharacterization);

            // Run a single trial
            var trialInfo = world.RunTrial(evaluationUnit.AgentPhenome, SearchType.MinimalCriteriaSearch,
                                           out var isGoalReached);

            // Set maze solved status
            evaluationUnit.IsMazeSolved = isGoalReached;

            // The number of time steps is effectively the number of 2-dimensional points in the behaviors array
            evaluationUnit.NumTimesteps = trialInfo.Behaviors.Count() / 2;

            // Set the trajectory of the agent
            evaluationUnit.AgentTrajectory = trialInfo.Behaviors;
        }
        public MazeNavigationView(IGenomeDecoder<NeatGenome, IBlackBox> genomeDecoder, MazeNavigationWorld<ITrialInfo> world) 
        {
            InitializeComponent();

            _genomeDecoder = genomeDecoder;
            _world = world;

            // Create a bitmap for the picturebox.
            int width = Width;
            int height = Height;
            _image = new Bitmap(width, height, ViewportPixelFormat);
            pbx.Image = _image;

            // Create background thread for running simulation alongside NEAT algorithm.
            //_simThread = new Thread(new ThreadStart(SimulationThread));
            //_simThread.IsBackground = true;
            //_simThread.Start();
        }
        /// <summary>
        ///     Runs the navigator through its corresponding maze and records data about said evaluation (e.g. solved status, time
        ///     steps, and trajectory).
        /// </summary>
        /// <param name="evaluationUnit">A single unit of evaluation containing a paired maze and navigator.</param>
        /// <param name="experimentParameters">Parameters that control the navigation simulation.</param>
        public static void EvaluateMazeNavigatorUnit(MazeNavigatorEvaluationUnit evaluationUnit,
            ExperimentParameters experimentParameters)
        {
            bool isGoalReached;

            // Build maze configuration
            MazeConfiguration mazeConfiguration =
                new MazeConfiguration(ExtractMazeWalls(evaluationUnit.MazePhenome.Walls),
                    ExtractStartEndPoint(evaluationUnit.MazePhenome.StartLocation),
                    ExtractStartEndPoint(evaluationUnit.MazePhenome.TargetLocation));

            // Create trajectory behavior characterization (in order to capture full trajectory of navigator)
            IBehaviorCharacterization behaviorCharacterization = new TrajectoryBehaviorCharacterization();

            // Create the maze navigation world
            MazeNavigationWorld<BehaviorInfo> world = new MazeNavigationWorld<BehaviorInfo>(mazeConfiguration.Walls,
                mazeConfiguration.NavigatorLocation, mazeConfiguration.GoalLocation,
                experimentParameters.MinSuccessDistance, experimentParameters.MaxTimesteps, behaviorCharacterization);

            // Run a single trial
            BehaviorInfo trialInfo = world.RunTrial(evaluationUnit.AgentPhenome, SearchType.MinimalCriteriaSearch,
                out isGoalReached);

            // Set maze solved status
            evaluationUnit.IsMazeSolved = isGoalReached;

            // The number of time steps is effectively the number of 2-dimensional points in the behaviors array
            evaluationUnit.NumTimesteps = trialInfo.Behaviors.Count()/2;

            // Set the trajectory of the agent
            evaluationUnit.AgentTrajectory = trialInfo.Behaviors;
        }