void IFitnessFunction.update(SimulatorExperiment Experiment, Environment environment, instance_pack ip)
        {
            // Initialize variables on first time step
            if (ip.timeSteps == 1)
            {
                livingCost = 0;
                rewards    = 0;
                // Fitness values must be positive. Therefore, a high positive fitness is assigned in advance,
                // and the cost of living subtracts from it.
                // time / steps is the number of actual time steps, and the cost is multiplied by number of enemies
                fitness = (Experiment.evaluationTime / Experiment.timestep) * Experiment.numEnemies;
            }

            // Find closest active prey
            bool  allCaptured = true; // becomes false if an active prey is found
            Robot evolved     = ip.robots[0];

            for (int i = 1; i < ip.robots.Count; i++)
            {
                // Assumes all but first robot are EnemyRobot instances
                EnemyRobot er = (EnemyRobot)ip.robots[i];
                if (!er.disabled) // Not captured yet
                {
                    //Console.WriteLine("Robot "+i+" not disabled");

                    allCaptured = false;
                    // The collisionWithEvolved bool should always be the primary means of detecting these
                    // collisions, but the other call is here as a precaution. This check is needed because
                    // when the evolved bot normally collides with the enemy, the "undo" method is called,
                    // which prevents the collision from being detected using normal means in this method.
                    // Fortunately, the collisionWithEvolved member is used to remember when this collision
                    // occurs.
                    if (er.collisionWithEvolved || EngineUtilities.collide(evolved, er))
                    { // Reward evolved bot for colliding with prey, and disable prey
                        er.disabled = true;
                        er.stopped  = true;
                        rewards    += PREY_REWARD;
                        fitness    += PREY_REWARD; // This is the value that matters
                        //Console.WriteLine("\treward:" + rewards + " from " + PREY_REWARD);
                    }
                    else
                    { // Each active prey punishes bot for not being caltured yet
                        double distance = evolved.location.distance(er.location);
                        double cost     = distance / environment.maxDistance;
                        livingCost += cost;
                        fitness    -= cost; // This is the value that matters
                        //Console.WriteLine("\tCost: " + (distance / 1000.0) + " to be " + livingCost + " raw distance: " + distance);
                    }
                }
            }

            // End evaluation and stop accruing negative fitness if all prey are captured
            if (allCaptured)
            {                                                   // Disabling prevents further action
                ip.elapsed         = Experiment.evaluationTime; // force end time: only affects non-visual evaluation
                Experiment.running = false;                     // Ends visual evaluation
            }
        }
        // Schrum2: Add extra enemy robot after deault robots
        public override void initializeRobots(AgentBrain agentBrain, Environment e, float headingNoise, float sensorNoise, float effectorNoise, instance_pack ip)
        {
            // Debug:schrum2
            //Console.WriteLine("Init Robots");
            base.initializeRobots(agentBrain, e, headingNoise, sensorNoise, effectorNoise, ip);
            enemies = new List <EnemyRobot>();
            for (int i = 0; i < numEnemies; i++)
            {
                // schrum2: here is where the enemy robot is added
                // Location of evolved robot is needed to track it
                // Assumes that robot is in position 0 (problem?)
                EnemyRobot r = new EnemyRobot(robots[0], flee);
                enemies.Add(r);

                double _timestep = 0.0;
                if (ip == null)
                {
                    _timestep = this.timestep;
                }
                else
                {
                    _timestep = ip.timestep;
                }

                double nx = enemyX - i * enemyDeltaX;
                double ny = enemyY - i * enemyDeltaY;
                double h  = 0;

                // Alternative starting positions for enemies
                if (enemiesSurround)
                {
                    double evolvedX = robots[0].location.x;
                    double evolvedY = robots[0].location.y;

                    double radius = 200.0;

                    nx = evolvedX + radius * Math.Cos((i * 2.0 * Math.PI) / numEnemies);
                    ny = evolvedY + radius * Math.Sin((i * 2.0 * Math.PI) / numEnemies);
                    h  = Math.PI + i * (2 * Math.PI / numEnemies);
                }

                r.init(robots.Count, // id is last position in list of robots
                       nx, ny, h,    // starting position and heading
                       agentBrain,   // Has evolved brain (to avoid NullPointers, etc), but should never actually use it (problem?)
                       e, sensorNoise, effectorNoise, headingNoise, (float)_timestep);

                r.collisionPenalty = collisionPenalty;
                // Only add enemy if it is not already present
                if (robots.Count <= numEnemies) // Makes limiting assumption that this experiment will always be used with only one evolved bot and one enemy
                {
                    robots.Add(r);
                    //Console.WriteLine("Added enemy to list: " + robots.Count);
                }

                // Required so that experiment works properly in both visual and non-visual mode
                // (The non-visual mode takes the robots from the instance_pack instead of the experiment)
                if (ip != null && ip.robots.Count <= numEnemies)
                {
                    ip.robots.Add(r);
                    //Console.WriteLine("Added enemy to ip");
                }
            }
        }
        // Schrum2: Add extra enemy robot after deault robots
        public override void initializeRobots(AgentBrain agentBrain, Environment e, float headingNoise, float sensorNoise, float effectorNoise, instance_pack ip)
        {
            // Debug:schrum2
            //Console.WriteLine("Init Robots");
            base.initializeRobots(agentBrain, e, headingNoise, sensorNoise, effectorNoise, ip);
            enemies = new List<EnemyRobot>();
            for (int i = 0; i < numEnemies; i++)
            {

                // schrum2: here is where the enemy robot is added
                // Location of evolved robot is needed to track it
                // Assumes that robot is in position 0 (problem?)
                EnemyRobot r = new EnemyRobot(robots[0], flee);
                enemies.Add(r);

                double _timestep = 0.0;
                if (ip == null)
                {
                    _timestep = this.timestep;
                }
                else
                {
                    _timestep = ip.timestep;
                }

                double nx = enemyX - i * enemyDeltaX;
                double ny = enemyY - i * enemyDeltaY;
                double h = 0;

                // Alternative starting positions for enemies
                if (enemiesSurround)
                {
                    double evolvedX = robots[0].location.x;
                    double evolvedY = robots[0].location.y;

                    double radius = 200.0;

                    nx = evolvedX + radius*Math.Cos((i * 2.0 * Math.PI) / numEnemies);
                    ny = evolvedY + radius*Math.Sin((i * 2.0 * Math.PI) / numEnemies);
                    h = Math.PI + i * (2 * Math.PI / numEnemies);
                }

                r.init(robots.Count, // id is last position in list of robots
                    nx, ny, h, // starting position and heading
                    agentBrain, // Has evolved brain (to avoid NullPointers, etc), but should never actually use it (problem?) 
                    e, sensorNoise, effectorNoise, headingNoise, (float)_timestep);

                r.collisionPenalty = collisionPenalty;
                // Only add enemy if it is not already present
                if (robots.Count <= numEnemies) // Makes limiting assumption that this experiment will always be used with only one evolved bot and one enemy
                {
                    robots.Add(r);
                    //Console.WriteLine("Added enemy to list: " + robots.Count);
                }

                // Required so that experiment works properly in both visual and non-visual mode
                // (The non-visual mode takes the robots from the instance_pack instead of the experiment)
                if (ip != null && ip.robots.Count <= numEnemies)
                {
                    ip.robots.Add(r);
                    //Console.WriteLine("Added enemy to ip");
                }
            }
        }