/// <inheritdoc />
        /// <summary>
        ///     Runs an agent (i.e. the maze navigator) through a collection of mazes until the minimal criteria is satisfied.
        /// </summary>
        /// <param name="agent">The maze navigator brain (ANN).</param>
        /// <param name="currentGeneration">The current generation or evaluation batch.</param>
        /// <param name="evaluationLogger">Reference to the evaluation logger.</param>
        /// <returns>A behavior info (which is a type of behavior-based trial information).</returns>
        public BehaviorInfo Evaluate(IBlackBox agent, uint currentGeneration,
                                     IDataLogger evaluationLogger)
        {
            var curSuccesses = 0;

            // TODO: Note that this will get overwritten until the last successful attempt (may need a better way of handling this for logging purposes)
            var trialInfo = BehaviorInfo.NoBehavior;

            for (var cnt = 0; cnt < _multiMazeWorldFactory.NumMazes && curSuccesses < _agentNumSuccessesCriteria; cnt++)
            {
                ulong threadLocalEvaluationCount;
                lock (_evaluationLock)
                {
                    // Increment evaluation count
                    threadLocalEvaluationCount = EvaluationCount++;
                }

                // Generate new behavior characterization
                var behaviorCharacterization = _behaviorCharacterizationFactory.CreateBehaviorCharacterization();

                // Generate a new maze world
                var world = _multiMazeWorldFactory.CreateMazeNavigationWorld(cnt, behaviorCharacterization);

                // Run a single trial
                trialInfo = world.RunTrial(agent, SearchType.MinimalCriteriaSearch, out var goalReached);

                // Set the objective distance
                trialInfo.ObjectiveDistance = world.GetDistanceToTarget();

                // Log trial information
                evaluationLogger?.LogRow(new List <LoggableElement>
                {
                    new LoggableElement(EvaluationFieldElements.Generation, currentGeneration),
                    new LoggableElement(EvaluationFieldElements.EvaluationCount, threadLocalEvaluationCount),
                    new LoggableElement(EvaluationFieldElements.StopConditionSatisfied, StopConditionSatisfied),
                    new LoggableElement(EvaluationFieldElements.RunPhase, RunPhase.Primary),
                    new LoggableElement(EvaluationFieldElements.IsViable,
                                        trialInfo.DoesBehaviorSatisfyMinimalCriteria)
                },
                                         world.GetLoggableElements());

                // If the navigator reached the goal, update the running count of successes
                if (goalReached)
                {
                    curSuccesses++;
                }
            }

            // If the number of successful maze navigations was equivalent to the minimum required,
            // then the minimal criteria has been satisfied
            if (curSuccesses >= _agentNumSuccessesCriteria)
            {
                trialInfo.DoesBehaviorSatisfyMinimalCriteria = true;
            }

            return(trialInfo);
        }
        /// <summary>
        ///     Runs a agent (i.e. maze navigator brain) through a single maze trial.
        /// </summary>
        /// <param name="agent">The maze navigator brain (ANN).</param>
        /// <param name="currentGeneration">The current generation or evaluation batch.</param>
        /// <param name="evaluationLogger">Reference to the evaluation logger.</param>
        /// <returns>A fitness info (which is a function of the euclidean distance to the target).</returns>
        public BehaviorInfo Evaluate(IBlackBox agent, uint currentGeneration,
                                     IDataLogger evaluationLogger)
        {
            lock (_evaluationLock)
            {
                // Increment evaluation count
                EvaluationCount++;
            }

            // Generate new behavior characterization
            var behaviorCharacterization = _behaviorCharacterizationFactory.CreateBehaviorCharacterization();

            // Instantiate the maze world
            var world = _multiMazeWorldFactory.CreateMazeNavigationWorld(behaviorCharacterization);

            // Run a single trial
            var trialInfo = world.RunTrial(agent, SearchType.NoveltySearch, out var goalReached);

            // Set the objective distance
            trialInfo.ObjectiveDistance = world.GetDistanceToTarget();

            // Set the stop condition to the outcome
            if (goalReached)
            {
                StopConditionSatisfied = true;
            }

            // Log trial information (only log for non-bridging evaluations)
            evaluationLogger?.LogRow(new List <LoggableElement>
            {
                new LoggableElement(EvaluationFieldElements.Generation, currentGeneration),
                new LoggableElement(EvaluationFieldElements.EvaluationCount, EvaluationCount),
                new LoggableElement(EvaluationFieldElements.StopConditionSatisfied, StopConditionSatisfied),
                new LoggableElement(EvaluationFieldElements.RunPhase, RunPhase.Initialization)
            },
                                     world.GetLoggableElements());

            return(trialInfo);
        }