Пример #1
0
        /// <summary>
        /// Called from the Arena, when a bot calls the Arena.Cannon() method
        ///
        /// The Cannon() function fires a missile heading a specified range and direction.
        /// Cannon() returns 1 (true) if a missile was fired, or 0 (false) if the cannon is reloading.
        /// Degree is forced into the range 0-359 as in Scan() and Drive().
        /// Range can be 0-700, with greater ranges truncated to 700.
        ///
        /// Examples:
        ///    degree = 45;                              // set a direction to test
        ///    if ((range=Scan(robot, degree, 2)) > 0)   // see if a target is there
        ///      Cannon(robot, degree, range);           // fire a missile
        /// </summary>
        /// <param name="robot"></param>
        /// <param name="degree"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public bool FireCannon(Robot robot, int degree, int range)
        {
            degree = Arena.DegreeTo360(degree);
            if (range < 0)
            {
                range = 0;
            }
            if (range > 700)
            {
                range = 700;
            }

            BotAssembly bot = Bots.Find(botAssembly => botAssembly.Id == robot.Id);

            if (bot.MissilesInFlight < MaxMissles)
            {
                bot.MissilesInFlight++;
                Missiles.Add(new Missile
                {
                    Id       = robot.Id,
                    Speed    = 100,
                    Location = new PointF {
                        X = bot.Location.X, Y = bot.Location.Y
                    },
                    Direction = degree,
                    Range     = range
                });

                return(true);
            }

            return(false);
        }
Пример #2
0
        /// <summary>
        /// Called from the Arena, when a bot calls the Arena.Scan() method
        ///
        /// The Scan() function invokes the robot's scanner, at a specified degree and resolution.
        /// Scan() returns 0 if no robots are within the scan range or a positive integer representing
        /// the  range to the closest robot.  Degree should be within the range 0-359, otherwise degree
        /// is forced into 0-359 by a modulo 360 operation, and made positive if necessary.
        /// Resolution controls the scanner's sensing resolution, up to +/- 10 degrees.
        ///
        /// Examples:
        ///   range = Scan(robot, 45, 0);   // scan 45, with no variance
        ///   range = Scan(robot, 365, 10); // scans the range from 355 to 15
        /// </summary>
        /// <param name="robot"></param>
        /// <param name="degree"></param>
        /// <param name="resolution"></param>
        /// <returns></returns>
        public int Scan(Robot robot, int degree, int resolution)
        {
            degree = Arena.DegreeTo360(degree);
            if (resolution < 0)
            {
                resolution = 0;
            }
            if (resolution > MaxScanResolution)
            {
                resolution = MaxScanResolution;
            }

            // Get the BotAssembly of the given robot from our list of robots
            BotAssembly botAssembly = Bots.Find(ba => ba.Id == robot.Id);

            // Update these for display
            botAssembly.ScanDirection  = degree;
            botAssembly.ScanResolution = resolution;

            // Iterate all bots (Max of 4 bots in the game)
            foreach (var bot in Bots)
            {
                // As long as it is not the given robot
                if (bot != botAssembly)
                {
                    // Plot a course from this bot to the given methods bot
                    int course = Arena.PlotCourse((int)bot.Location.X,
                                                  (int)bot.Location.Y,
                                                  (int)botAssembly.Location.X,
                                                  (int)botAssembly.Location.Y);

                    // Given the Scan resolution ( +/- 10 degrees maximum ) is there a bot out there?
                    int degStart = Arena.DegreeTo360(degree - resolution);
                    int degEnd   = Arena.DegreeTo360(degree + resolution);
                    for (int scanResolution = degStart; scanResolution <= degEnd; ++scanResolution)
                    {
                        if (course == scanResolution)
                        {
                            // Return the range to the discovered target
                            int range = Math.Abs(Arena.Distance((int)bot.Location.X,
                                                                (int)bot.Location.Y,
                                                                (int)botAssembly.Location.X,
                                                                (int)botAssembly.Location.Y));

                            // Return the range to the discovered robot if distance is MaxScanRange or less
                            return(range);//range >= MaxScanRange ? range : 0;
                        }
                    }
                }
            }

            // No robot found
            return(0);
        }
Пример #3
0
        /// <summary>
        /// Initialize the given robot with the given id, assign a random
        /// starting location and call the robots InitMethod
        /// </summary>
        /// <param name="bot"></param>
        /// <param name="id"></param>
        private static void Ininialize(ref BotAssembly bot, int id)
        {
            bot.Id             = id;
            bot.Location.X     = Arena.Rand(ArenaWidth) - 1;
            bot.Location.Y     = Arena.Rand(ArenaHeight - 1);
            bot.LastLocation.X = bot.Location.X;
            bot.LastLocation.Y = bot.Location.Y;

            // Zero by default : bot.Speed = 0; bot.LastSpeed = 0; bot.Damage = 0; bot.Direction = 0; bot.ScanDirection = 0; bot.MissilesInFlight = 0;
            bot.Assembly.GetType(Namespace + "." + bot.ClassName).GetProperty("Id").SetValue(bot.AssemblyInstance, id, null);
            bot.Assembly.GetType(Namespace + "." + bot.ClassName).GetMethod(InitMethod).Invoke(bot.AssemblyInstance, null);
        }
Пример #4
0
        /// <summary>
        /// Load given robots, compile, instantiate and initialize
        /// Sets loaded robots Id's and calls each robots Initialize method
        /// </summary>
        /// <param name="botsSource"></param>
        /// <returns></returns>
        public bool Load(string[] botsSource)
        {
            string currentSourceFile = String.Empty;

            Bots.Clear();
            if (null != Errors)
            {
                Errors.Clear();
            }

            try
            {
                int botId = 1;
                foreach (var sourceFile in botsSource)
                {
                    // Create a unique assembly name so we can pit the same bot class against itself
                    string assemblyName = Path.GetFileNameWithoutExtension(sourceFile) + botId;
                    currentSourceFile = sourceFile;
                    BotAssembly bot = Compile(sourceFile, assemblyName);

                    if (null == bot || null == bot.AssemblyInstance)
                    {
                        return(false);
                    }
                    Ininialize(ref bot, ++botId);
                    Bots.Add(bot);
                }
            }
            catch (Exception ex)
            {
                if (null != Errors)
                {
                    Errors.Add(new CompilerError(currentSourceFile, 0, 0, "0", ex.ToString()));
                }
                return(false);
            }

            return(true);
        }
Пример #5
0
        /// <summary>
        /// The Execute method is called repeatedly and runs the robots
        /// on the battle field calling each robots Execute method, updating
        /// in flight missiles, checking for collisions and updating damage.
        /// </summary>
        public bool Execute()
        {
            int totalDamage = 0;

            // Work out how long since we were last here in seconds
            double gameTime    = _timer.ElapsedMilliseconds / 1000.0;
            double elapsedTime = gameTime - _lastTime;

            _lastTime = gameTime;

            // Remove any missiles that died last game frame
            if (_deadMissiles)
            {
                RemoveDeadMissles();
            }

            // Update any missiles
            foreach (var missile in Missiles)
            {
                missile.LastLocation = missile.Location;

                // Update robot position based on the velocity
                missile.Location.X += (float)Math.Sin(missile.Direction * Math.PI / 180) * missile.Speed * (float)elapsedTime;
                missile.Location.Y += (float)Math.Cos(missile.Direction * Math.PI / 180) * missile.Speed * (float)elapsedTime;
                missile.Range      -= Arena.Distance((int)missile.LastLocation.X, (int)missile.LastLocation.Y, (int)missile.Location.X, (int)missile.Location.Y);

                // If a missile is leaving the arena, i.e. hitting a wall, explode it by setting it's range to 0
                if (missile.Location.X < 0 || missile.Location.Y < 0 ||
                    missile.Location.X > ArenaWidth - 1 || missile.Location.Y > ArenaHeight - 1)
                {
                    missile.Range = 0;
                }

                // Missile has reached it's defined range.
                if (missile.Range <= 0)
                {
                    // Explode the missile
                    // TODO Determine any damage to bots in the area
                    // Iterate each robot. Get range to this missile. If in damage range, apply the damage.

                    // Update the bot that fired the missile
                    Missile     missile1 = missile;
                    BotAssembly bot      = Bots.Find(botAssembly => botAssembly.Id == missile1.Id);
                    bot.MissilesInFlight--;

                    // Mark missile as dead so we can clean it up
                    missile.Dead  = true;
                    _deadMissiles = true;
                }
            }

            // Update bots
            foreach (var bot in Bots)
            {
                totalDamage += bot.Damage;

                // 100% damaged bots do nothing
                if (bot.Damage != 100)
                {
                    // Check if robot is changing there speed
                    // TODO Need to ramp up/down to the robots set speed
                    //if (bot.Speed != bot.LastSpeed)
                    //{
                    //    if (bot.Direction >= 0 && bot.Direction <= 180)
                    //    {
                    //        bot.Velocity.X += 40;
                    //        bot.Velocity.Y += 40;
                    //    }
                    //    else
                    //    {
                    //        bot.Velocity.X -= 40;
                    //        bot.Velocity.Y -= 40;
                    //    }

                    //    bot.LastSpeed = bot.Speed;
                    //}

                    bot.LastLocation = bot.Location;

                    // Update robot position based on the velocity
                    bot.Location.X += (float)Math.Sin(bot.Direction * Math.PI / 180) * bot.Speed * (float)elapsedTime;
                    bot.Location.Y += (float)Math.Cos(bot.Direction * Math.PI / 180) * bot.Speed * (float)elapsedTime;

                    // Fix the robots position to not leave the Arena
                    if (bot.Location.X < 0)
                    {
                        bot.Location.X = 0;
                    }
                    if (bot.Location.X > ArenaWidth - 1)
                    {
                        bot.Location.X = ArenaWidth - 1;
                    }
                    if (bot.Location.Y < 0)
                    {
                        bot.Location.Y = 0;
                    }
                    if (bot.Location.Y > ArenaHeight - 1)
                    {
                        bot.Location.Y = ArenaHeight - 1;
                    }

                    // TODO Add collision detection and damage

                    // Have robots perform an execution step
                    bot.Assembly.GetType(Namespace + "." + bot.ClassName).GetMethod(ExecuteMethod).Invoke(bot.AssemblyInstance, null);
                }
            }

            return(totalDamage == 300 ? false : true);
        }
Пример #6
0
        /// <summary>
        /// Initialize the given robot with the given id, assign a random
        /// starting location and call the robots InitMethod
        /// </summary>
        /// <param name="bot"></param>
        /// <param name="id"></param>
        private static void Ininialize(ref BotAssembly bot, int id)
        {
            bot.Id = id;
            bot.Location.X = Arena.Rand(ArenaWidth)-1;
            bot.Location.Y = Arena.Rand(ArenaHeight-1);
            bot.LastLocation.X = bot.Location.X;
            bot.LastLocation.Y = bot.Location.Y;

            // Zero by default : bot.Speed = 0; bot.LastSpeed = 0; bot.Damage = 0; bot.Direction = 0; bot.ScanDirection = 0; bot.MissilesInFlight = 0;
            bot.Assembly.GetType(Namespace + "." + bot.ClassName).GetProperty("Id").SetValue(bot.AssemblyInstance, id, null);
            bot.Assembly.GetType(Namespace + "." + bot.ClassName).GetMethod(InitMethod).Invoke(bot.AssemblyInstance, null);
        }