Example #1
0
        /// <summary>
        /// This method is called by the game whenever our robot has scanned another robot by turning the radar.
        /// Note: Our radar is turning around forever at maximum speed, so this event is called as soon as the
        /// radar "hits" another robot.
        /// </summary>
        /// <param name="scannedRobotEvent">The scanned robot event containing data about the scanned robot.</param>
        public override void OnScannedRobot(ScannedRobotEvent scannedRobotEvent)
        {
            // Exit this method, if the scanned robot is another sentry robot
            if (scannedRobotEvent.IsSentryRobot)
            {
                return;
            }

            // Get the distance from our robot to the scanned robot
            double distance = scannedRobotEvent.Distance;
            // Calculate the angle in radians to the scanned robot.
            // Angle = our robot's heading (angle) + the bearing (delta angle) to the scanned robot.
            double angle = HeadingRadians + scannedRobotEvent.BearingRadians;

            // Prepare an entry with scanned robot data that we can store in our scanned data map
            ScannedRobotData robotData = new ScannedRobotData();

            // Store the name of the scanned robot
            robotData.name = scannedRobotEvent.Name;
            // Store the time when the robot was scanned
            robotData.time = scannedRobotEvent.Time;
            // Calculate and store the x coordinate of the scanned robot (using the Robocode coordinate system)
            robotData.x = X + Math.Sin(angle) * distance;
            // Calculate and store the y coordinate of the scanned robot (using the Robocode coordinate system)
            robotData.y = Y + Math.Cos(angle) * distance;

            // Store the entry of scanned robot entry in our map over scanned robot data.
            // We use the name of the robot as the key for accessing the scanned data for that particular robot later
            scannedRobotData.Remove(robotData.name);
            scannedRobotData.Add(robotData.name, robotData);
        }
Example #2
0
        /// <summary>
        /// This method is called by the game whenever another robot dies.
        /// </summary>
        /// <param name="robotDeathEvent">The robot death event containing data about the robot that died.</param>
        public override void OnRobotDeath(RobotDeathEvent robotDeathEvent)
        {
            // Remove the scanned robot data for the robot that died.
            // This data is useless now, and will only confuse our robot if it stays in our scanned robot data.
            scannedRobotData.Remove(robotDeathEvent.Name);

            // Remove our global target, if our target was the robot that died, but only if we have a current target
            if (target != null && target.name.Equals(robotDeathEvent.Name))
            {
                target = null;
            }
        }
Example #3
0
        /// <summary>
        /// This method is called by the game before each turn with the current status of our robot.
        /// </summary>
        /// <param name="statusEvent">The status event containing status data for our robot.</param>
        public override void OnStatus(StatusEvent statusEvent)
        {
            // 'newTarget' is used for selecting our new target to fire at.
            // Set this to null here, which means that we have no target... yet!
            ScannedRobotData newTarget = null;

            // Prepara a list for containing all scanned robot data.
            List <ScannedRobotData> currentScanData = new List <ScannedRobotData>();

            // Add scanned robot data that is not too old. When data is more than 360 / 45 degrees = 8 turns old,
            // our radar should retrieve new information about a particular robot, unless it has died or is
            // out of the scan radius (1200 units). Anyways, the robot will probably have moved far ways since then.

            foreach (ScannedRobotData robotData in scannedRobotData.Values)
            {
                // Add entry if the the delta time (scanned event time - status event time) is less than or equal to 8 turns
                if (statusEvent.Time - robotData.time <= 8)
                {
                    currentScanData.Add(robotData);
                }
            }

            // Now, make a copy of current scan data that should contain target candidates
            List <ScannedRobotData> targetCandidates = new List <ScannedRobotData>(currentScanData);

            // Prepare a new list for containing scanned robot data, but only with robots
            List <ScannedRobotData> newCurrentScanData = new List <ScannedRobotData>();

            // Add all target candidates that are inside our sentry robot's attack range as we
            // will not be able to harm robots outside this range with our gun fire (is a game rule).
            foreach (ScannedRobotData robotData in currentScanData)
            {
                // Add robot data if its location is inside the sentry attack range
                if (IsInsideSentryAttackRange(robotData.x, robotData.y))
                {
                    newCurrentScanData.Add(robotData);
                }
            }
            // Save the new list containing robot scan data as the current robot scan data list
            currentScanData = newCurrentScanData;

            // If we don't have any target candidates, we have no candidates to fire at.
            // However, we will then use the current scan data for moving out robot as close to the nearest robot
            // outside the sentry robot's attack range, so we have a better chance to hit it when it moves too
            // close to the border.
            if (targetCandidates.Count == 0)
            {
                targetCandidates = new List <ScannedRobotData>(currentScanData);
            }

            // Now, pick the new target robot among the target candidates based on how far those are to our robot.
            // Pick the robot closest to our robot.

            double shortestDistance = double.MaxValue; // Initialize shortest distance seen, to maximum value

            foreach (ScannedRobotData robotData in currentScanData)
            {
                // Calculate the distance to the robot based on the hypotenuse (Pythagoras)
                double distance = DistanceTo(robotData.x, robotData.y);
                // Check if the distance is shorter than shortest distance calculated so far
                if (distance < shortestDistance)
                {
                    // If the distance is shorter then save the calculated distance as the new shortest distance
                    shortestDistance = distance;
                    // Save the robot data as our new target robot
                    newTarget = robotData;
                }
            }

            // Check if we got a new target robot
            if (newTarget != null)
            {
                // We got a new target robot..

                // Calculate the target angle of the robot
                double targetAngle = Math.Atan2(newTarget.x - X, newTarget.y - Y);
                // Normalize the target angle so that the angle is kept within the range [0, PI[
                targetAngle = Utils.NormalAbsoluteAngle(targetAngle);

                // Calculate the delta gun angle, i.e. how much of robot should be moved to the right.
                double deltaGunAngle = Utils.NormalRelativeAngle(targetAngle - GunHeadingRadians);

                // Set the gun to turn right the number of radians stored in the calculated delta gun angle.
                // Note: The setTurnGunRightRadians() will first be executed, when the execute() method is called.
                // If the delta gun angle is negative, it will automatically be moved in the opposite direction.
                SetTurnGunRightRadians(deltaGunAngle);

                // Check that the radar turn has almost completed (has less than 1 degrees left to turn) and
                // that the target robot is inside the entry attack range.
                if (RadarTurnRemaining < 1 && IsInsideSentryAttackRange(newTarget.x, newTarget.y))
                {
                    // Calculate the fire power we should use when firing at our target..

                    // We want to use the maximum bullet power 3, when the target is within 100 units and
                    // the bullet power should become lesser the longer the distance is to our target.
                    // Hence, we calculate the fire power as 3 * 100 / distance to target.
                    double firePower = 300 / DistanceTo(newTarget.x, newTarget.y);

                    // Set our gun to fire with the calculated amount of fire power.
                    // Note: If the fire power is less than the minimum fire power 0.1 the gun will not fire.
                    // If the fire power is greater than the maximum fire power 3, then gun will use 3 as fire power.
                    SetFire(firePower);
                }

                // Paint a circle on our current target (debugging graphics)
                PaintCircle(newTarget.x, newTarget.y);
            }

            // Set our new target as our new "global" target, so that other methods can use it
            this.target = newTarget;
        }