示例#1
0
        public static void Repel(Robot rob1, Robot rob2)
        {
            double       fixedSep;
            DoubleVector fixedSepVector;
            var          e = SimOpt.SimOpts.CoefficientElasticity;

            var normal   = rob2.Position - rob1.Position;
            var currDist = normal.Magnitude();

            //If both bots are fixed or not moving and they overlap, move their positions directly.  Fixed bots can overlap when shapes sweep them together
            //or when they teleport or materialize on top of each other.  We move them directly apart as they are assumed to have no velocity
            //by scaling the normal vector by the amount they need to be separated.  Each bot is moved half of the needed distance without taking into consideration
            //mass or size.
            if (rob1.IsFixed && rob2.IsFixed || rob1.Velocity.Magnitude() < 0.0001 && rob2.Velocity.Magnitude() < 0.0001)
            {
                fixedSep       = (rob1.GetRadius(SimOpt.SimOpts.FixedBotRadii) + rob2.GetRadius(SimOpt.SimOpts.FixedBotRadii) - currDist) / 2;
                fixedSepVector = normal.Unit() * fixedSep;
                rob1.Position -= fixedSepVector;
                rob2.Position += fixedSepVector;
            }
            else
            {
                var totalMass = rob1.Mass + rob2.Mass;
                fixedSep       = rob1.GetRadius(SimOpt.SimOpts.FixedBotRadii) + rob2.GetRadius(SimOpt.SimOpts.FixedBotRadii) - currDist;
                fixedSepVector = normal.Unit() * (fixedSep / (1 + Math.Pow(55, 0.3 - e)));
                rob1.Position -= fixedSepVector * (rob2.Mass / totalMass);
                rob2.Position += fixedSepVector * (rob1.Mass / totalMass);
            }

            if (!double.IsFinite(1.0 / normal.Magnitude()))
            {
                return;
            }

            var m1 = rob1.Mass;
            var m2 = rob2.Mass;

            //If a bot is fixed, all the collision energy should be translated to the non-fixed bot so for
            //the purposes of calculating the force applied to the non-fixed bot, treat the fixed one as if it is very massive
            if (rob1.IsFixed)
            {
                m1 = 32000;
            }

            if (rob2.IsFixed)
            {
                m2 = 32000;
            }

            var unit = normal.Unit();
            var vel1 = rob1.Velocity;
            var vel2 = rob2.Velocity;

            //Project the bot's direction vector onto the unit vector and scale by velocity
            //These represent vectors we subtract from the bot's velocity to push the bot in a direction
            //appropriate to the collision.  This would be all we needed if the bots all massed the same.
            //It's possible the bots are already moving away from each other having "collided" last cycle.  If so,
            //we don't want to reverse them again and we don't want to add too much more further acceleration
            var projection = DoubleVector.Dot(vel1, unit) * 0.99;

            if (projection <= 0)
            { // bots are already moving away from one another
                projection = 0.000001;
            }
            var v1 = unit * projection;

            projection = DoubleVector.Dot(vel2, unit) * 0.99; // try damping things down a little

            if (projection >= 0)
            { // bots are already moving away from one another
                projection = -0.000001;
            }
            var v2 = unit * projection;

            //Now we need to factor in the mass of the bots.  These vectors represent the resistance to movement due
            //to the bot's mass
            var v1F = (v2 * (e + 1) * m2 + v1 * (m1 - e * m2)) * (1 / (m1 + m2));
            var v2F = (v1 * (e + 1) * m1 + v2 * (m2 - e * m1)) * (1 / (m1 + m2));

            //No reason to try to try to accelerate fixed bots
            if (!rob1.IsFixed)
            {
                rob1.Velocity -= v1 + v1F;
            }

            if (!rob2.IsFixed)
            {
                rob2.Velocity -= v2 + v2F;
            }

            //Update the touch senses
            Senses.Touch(rob1, rob2.Position.X, rob2.Position.Y);
            Senses.Touch(rob2, rob1.Position.X, rob1.Position.Y);

            //Update last touch variables
            rob1.LastTouched = rob2;
            rob2.LastTouched = rob1;

            //Update the refvars to reflect touching bots.
            Senses.LookOccurr(rob1, rob2);
            Senses.LookOccurr(rob2, rob1);
        }
示例#2
0
文件: Vegs.cs 项目: trichards57/DBNet
        private static void aggiungirob(IRobotManager robotManager, IBucketManager bucketManager)
        {
            if (!SimOpt.SimOpts.Specie.Any(s => CheckVegStatus(robotManager, s)))
            {
                return;
            }

            int r;

            do
            {
                r = ThreadSafeRandom.Local.Next(0, SimOpt.SimOpts.Specie.Count); // start randomly in the list of species
            } while (!CheckVegStatus(robotManager, SimOpt.SimOpts.Specie[r]));

            var x = ThreadSafeRandom.Local.Next(Robot.RobSize / 2, SimOpt.SimOpts.FieldWidth - Robot.RobSize / 2);
            var y = ThreadSafeRandom.Local.Next(Robot.RobSize / 2, SimOpt.SimOpts.FieldHeight - Robot.RobSize / 2);

            if (SimOpt.SimOpts.Specie[r].Name == "" || SimOpt.SimOpts.Specie[r].Path == "Invalid Path")
            {
                return;
            }

            var a = DnaManipulations.RobScriptLoad(robotManager, bucketManager, System.IO.Path.Join(SimOpt.SimOpts.Specie[r].Path,
                                                                                                    SimOpt.SimOpts.Specie[r].Name));

            if (a == null)
            {
                SimOpt.SimOpts.Specie[r].Native = false;
                return;
            }

            //Check to see if we were able to load the bot.  If we can't, the path may be wrong, the sim may have
            //come from another machine with a different install path.  Set the species path to an empty string to
            //prevent endless looping of error dialogs.
            if (!a.Exists)
            {
                SimOpt.SimOpts.Specie[r].Path = "Invalid Path";
                return;
            }

            a.IsVegetable = SimOpt.SimOpts.Specie[r].Veg;
            if (a.IsVegetable)
            {
                a.Chloroplasts = SimOptions.StartChlr;
            }

            a.IsFixed                 = SimOpt.SimOpts.Specie[r].Fixed;
            a.CantSee                 = SimOpt.SimOpts.Specie[r].CantSee;
            a.DnaDisabled             = SimOpt.SimOpts.Specie[r].DisableDna;
            a.MovementSysvarsDisabled = SimOpt.SimOpts.Specie[r].DisableMovementSysvars;
            a.CantReproduce           = SimOpt.SimOpts.Specie[r].CantReproduce;
            a.IsVirusImmune           = SimOpt.SimOpts.Specie[r].VirusImmune;
            a.IsCorpse                = false;
            a.IsDead       = false;
            a.Body         = 1000;
            a.Mutations    = 0;
            a.OldMutations = 0;
            a.LastMutation = 0;
            a.SonNumber    = 0;
            a.Parent       = null;
            Array.Clear(a.Memory, 0, a.Memory.Length);

            if (a.IsFixed)
            {
                a.Memory[216] = 1;
            }

            a.Position = new DoubleVector(x, y);

            a.Aim = ThreadSafeRandom.Local.NextDouble() * Math.PI * 2;
            a.Memory[MemoryAddresses.SetAim] = (int)a.Aim * 200;

            //Bot is already in a bucket due to the prepare routine
            bucketManager.UpdateBotBucket(a);
            a.Energy = SimOpt.SimOpts.Specie[r].Stnrg;
            a.MutationProbabilities = SimOpt.SimOpts.Specie[r].Mutables;

            a.VirusTimer    = 0;
            a.VirusShot     = null;
            a.NumberOfGenes = DnaManipulations.CountGenes(a.Dna);

            a.GenMut = (double)a.Dna.Count / RobotsManager.GeneticSensitivity;

            a.Memory[MemoryAddresses.DnaLenSys] = a.Dna.Count;
            a.Memory[MemoryAddresses.GenesSys]  = a.NumberOfGenes;

            a.ChloroplastsDisabled = SimOpt.SimOpts.Specie[r].NoChlr;

            for (var i = 0; i < 7; i++)
            {
                a.Skin[i] = SimOpt.SimOpts.Specie[r].Skin[i];
            }

            a.Color = SimOpt.SimOpts.Specie[r].Color;
            Senses.MakeOccurrList(a);
        }