public EvolutionDreamer(ItemOptionsArco itemOptions, BotShellColorsDNA shellColors, int numTrackedBots) { _itemOptions = itemOptions; _shellColors = shellColors; _mutateArgs = GetMutateArgs(itemOptions); _dreamWorld = new OfflineWorld(BOUNDRYSIZE, itemOptions); _trackedBots = new TrackedBot[numTrackedBots]; for (int cntr = 0; cntr < numTrackedBots; cntr++) { _trackedBots[cntr] = new TrackedBot(_lock); } _timer = new System.Timers.Timer(); _timer.AutoReset = false; _timer.Interval = 250; _timer.Elapsed += Timer_Elapsed; _timer.Start(); _ruleTimer = new System.Timers.Timer(); _ruleTimer.AutoReset = false; _ruleTimer.Interval = 50; _ruleTimer.Elapsed += RuleTimer_Elapsed; _ruleTimer.Start(); _ruleElapsed = _ruleTimer.Interval / 1000d; }
public NPCNest(NPCNestDNA dna, double radius, World world, Map map, KeepItems2D keepItems2D, MaterialIDs materialIDs, Viewport3D viewport, EditorOptions editorOptions, ItemOptionsArco itemOptions, IGravityField gravity, DragHitShape dragPlane) { // Store stuff _world = world; _map = map; _keepItems2D = keepItems2D; _materialIDs = materialIDs; _viewport = viewport; _editorOptions = editorOptions; _itemOptions = itemOptions; _gravity = gravity; _dragPlane = dragPlane; // DNA NPCNestDNA fixedDNA = GetFinalDNA(dna); _shellColors = fixedDNA.ShellColors; _botDNA = fixedDNA.BotDNA; _weaponDNA = fixedDNA.WeaponDNA; //TODO: Hand this a winner list, and filter criteria _dreamer = new EvolutionDreamer(_itemOptions, _shellColors, 4); //TODO: Num bots should come from item options _dreamer.WeaponDNA = EvolutionDreamer.GetRandomDNA().Item2; #region WPF Model var models = GetModel(_shellColors, radius); this.Model = models.Item1; _eggModels = models.Item2; _rotateTransform = new QuaternionRotation3D(); _translateTransform = new TranslateTransform3D(); Transform3DGroup transform = new Transform3DGroup(); transform.Children.Add(new RotateTransform3D(_rotateTransform)); transform.Children.Add(_translateTransform); ModelVisual3D visual = new ModelVisual3D(); visual.Transform = transform; visual.Content = this.Model; this.Visuals3D = new Visual3D[] { visual }; #endregion // Energy tank _energy = new Container(); _energy.QuantityMax = _itemOptions.Nest_Energy_Max * radius; _energy.QuantityCurrent = _energy.QuantityMax * .5d; // Finish this.Token = TokenGenerator.NextToken(); this.Radius = radius; this.CreationTime = DateTime.UtcNow; }
public OfflineWorld(double size, ItemOptionsArco itemOptions) { const int INTERVAL = 50; this.Size = size; _thread = new TimerCreateThread <WorldVars>(Prep, Tick, TearDown, itemOptions, size, INTERVAL); _thread.Interval = INTERVAL; _thread.Start(); }
//TODO: Make a random version //private static FitnessTracker GetRandomRules(Bot bot = null) private static MutateUtility.NeuronMutateArgs GetMutateArgs(ItemOptionsArco options) { MutateUtility.NeuronMutateArgs retVal = null; MutateUtility.MuateArgs neuronMovement = new MutateUtility.MuateArgs(false, options.Neuron_PercentToMutate, null, null, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.Neuron_MovementAmount)); // neurons are all point3D (positions need to drift around freely. percent doesn't make much sense) MutateUtility.MuateArgs linkMovement = new MutateUtility.MuateArgs(false, options.Link_PercentToMutate, new Tuple <string, MutateUtility.MuateFactorArgs>[] { Tuple.Create("FromContainerPosition", new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.LinkContainer_MovementAmount)), Tuple.Create("FromContainerOrientation", new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, options.LinkContainer_RotateAmount)) }, new Tuple <PropsByPercent.DataType, MutateUtility.MuateFactorArgs>[] { Tuple.Create(PropsByPercent.DataType.Double, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.Link_WeightAmount)), // all the doubles are weights, which need to be able to cross over zero (percents can't go + to -) Tuple.Create(PropsByPercent.DataType.Point3D, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.Link_MovementAmount)), // using a larger value for the links }, null); retVal = new MutateUtility.NeuronMutateArgs(neuronMovement, null, linkMovement, null); return(retVal); }
public SensorVision(EditorOptions options, ItemOptionsArco itemOptions, ShipPartDNA dna, Map map, double searchRadius, Type filterType = null) : base(options, dna, itemOptions.VisionSensor_Damage.HitpointMin, itemOptions.VisionSensor_Damage.HitpointSlope, itemOptions.VisionSensor_Damage.Damage) { _itemOptions = itemOptions; _map = map; _filterType = filterType; this.Design = new SensorVisionDesign(options, true); this.Design.SetDNA(dna); double radius, volume; GetMass(out _mass, out volume, out radius, out _scaleActual, dna, itemOptions); this.Radius = radius; _neurons = CreateNeurons(dna, itemOptions, itemOptions.VisionSensor_NeuronDensity, true, true); #region Store stats about neurons if (_neurons.Length == 0) { throw new ApplicationException("CreateNeurons should have guaranteed at least one neuron"); } else if (_neurons.Length == 1) { // Since the neuron was forced to not be at the origin, just take the offset from origin (a single neuron vision // field is pretty useless anyway) _neuronDistBetween = _neurons[0].Position.ToVector().Length; } else { // Get the distance between each neuron List<Tuple<int, int, double>> distances = new List<Tuple<int, int, double>>(); for (int outer = 0; outer < _neurons.Length - 1; outer++) { for (int inner = outer + 1; inner < _neurons.Length; inner++) { double distance = (_neurons[outer].Position - _neurons[inner].Position).LengthSquared; distances.Add(Tuple.Create(outer, inner, distance)); } } // Get the average of the minimum distance of each index _neuronDistBetween = Enumerable.Range(0, _neurons.Length). Select(o => distances. Where(p => p.Item1 == o || p.Item2 == o). // get the disances that mention this index Min(p => p.Item3)). // only keep the smallest of those distances Average(); // get the average of all the mins } // Find the one that's farthest away from the origin (since they form a circle, there will be an outer ring of them that // are about the same distance from the center) _neuronMaxRadius = _neurons.Max(o => o.PositionLength); #endregion this.SearchRadius = searchRadius; // need to set this last, because it populates _distProps }
//TODO: Make a random version //private static FitnessTracker GetRandomRules(Bot bot = null) private static MutateUtility.NeuronMutateArgs GetMutateArgs(ItemOptionsArco options) { MutateUtility.NeuronMutateArgs retVal = null; MutateUtility.MuateArgs neuronMovement = new MutateUtility.MuateArgs(false, options.Neuron_PercentToMutate, null, null, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.Neuron_MovementAmount)); // neurons are all point3D (positions need to drift around freely. percent doesn't make much sense) MutateUtility.MuateArgs linkMovement = new MutateUtility.MuateArgs(false, options.Link_PercentToMutate, new Tuple<string, MutateUtility.MuateFactorArgs>[] { Tuple.Create("FromContainerPosition", new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.LinkContainer_MovementAmount)), Tuple.Create("FromContainerOrientation", new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, options.LinkContainer_RotateAmount)) }, new Tuple<PropsByPercent.DataType, MutateUtility.MuateFactorArgs>[] { Tuple.Create(PropsByPercent.DataType.Double, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.Link_WeightAmount)), // all the doubles are weights, which need to be able to cross over zero (percents can't go + to -) Tuple.Create(PropsByPercent.DataType.Point3D, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.Link_MovementAmount)), // using a larger value for the links }, null); retVal = new MutateUtility.NeuronMutateArgs(neuronMovement, null, linkMovement, null); return retVal; }
public EvolutionDreamer(ItemOptionsArco itemOptions, BotShellColorsDNA shellColors, int numTrackedBots) { _shellColors = shellColors; _mutateArgs = GetMutateArgs(itemOptions); _dreamWorld = new OfflineWorld(BOUNDRYSIZE, itemOptions); _trackedBots = new TrackedBot[numTrackedBots]; for (int cntr = 0; cntr < numTrackedBots; cntr++) { _trackedBots[cntr] = new TrackedBot(_lock); } _timer = new System.Timers.Timer(); _timer.AutoReset = false; _timer.Interval = 250; _timer.Elapsed += Timer_Elapsed; _timer.Start(); _ruleTimer = new System.Timers.Timer(); _ruleTimer.AutoReset = false; _ruleTimer.Interval = 50; _ruleTimer.Elapsed += RuleTimer_Elapsed; _ruleTimer.Start(); _ruleElapsed = _ruleTimer.Interval / 1000d; }
public ArcBotNPC(BotDNA dna, int level, Point3D position, World world, Map map, KeepItems2D keepItems2D, MaterialIDs materialIDs, Viewport3D viewport, EditorOptions editorOptions, ItemOptionsArco itemOptions, IGravityField gravity, DragHitShape dragPlane, Point3D homingPoint, double homingRadius, bool runNeural, bool repairPartPositions) : base(dna, level, position, world, map, keepItems2D, materialIDs, viewport, editorOptions, itemOptions, gravity, dragPlane, homingPoint, homingRadius, runNeural, repairPartPositions) { }
public SensorHoming(EditorOptions options, ItemOptionsArco itemOptions, ShipPartDNA dna, Map map, Point3D homePoint, double homeRadius) : base(options, dna, itemOptions.HomingSensor_Damage.HitpointMin, itemOptions.HomingSensor_Damage.HitpointSlope, itemOptions.HomingSensor_Damage.Damage) { _itemOptions = itemOptions; _map = map; _homePoint = homePoint; _homeRadius = homeRadius; this.Design = new SensorHomingDesign(options, true); this.Design.SetDNA(dna); double radius, volume; SensorVision.GetMass(out _mass, out volume, out radius, out _scaleActual, dna, itemOptions); this.Radius = radius; _neurons = CreateNeurons(dna, itemOptions, itemOptions.HomingSensor_NeuronDensity, true); double scale = homeRadius / _neurons.Max(o => o.PositionLength); this.NeuronWorldPositions = _neurons.Select(o => (o.PositionUnit.Value * (o.PositionLength * scale)).ToPoint()).ToArray(); this.HomeRadius = homeRadius; }
public MotionController_Linear(EditorOptions options, ItemOptionsArco itemOptions, ShipPartDNA dna, AIMousePlate mousePlate) : base(options, dna, itemOptions.MotionController_Damage.HitpointMin, itemOptions.MotionController_Damage.HitpointSlope, itemOptions.MotionController_Damage.Damage) { _itemOptions = itemOptions; _mousePlate = mousePlate; this.Design = new MotionController_LinearDesign(options, true); this.Design.SetDNA(dna); double radius, volume; SensorVision.GetMass(out _mass, out volume, out radius, out _scaleActual, dna, itemOptions); this.Radius = radius; _neurons = SensorVision.CreateNeurons(dna, itemOptions, itemOptions.MotionController_Linear_NeuronDensity, false, false); BuildTerrain(); _distanceMult = _mousePlate.MaxXY / _neurons.Max(o => o.PositionLength); }
public static (BotDNA bot, WeaponDNA weapon) GetRandomDNA(ItemOptionsArco itemOptions, BotShellColorsDNA shellColors = null, WeaponDNA weapon = null) { Random rand = StaticRandom.GetRandomForThread(); BotDNA bot = new BotDNA() { UniqueID = Guid.NewGuid(), Lineage = Guid.NewGuid().ToString(), Generation = 0, DraggingMaxVelocity = rand.NextPercent(5, .25), DraggingMultiplier = rand.NextPercent(20, .25), }; #region Parts List <ShipPartDNA> parts = new List <ShipPartDNA>(); double partSize; // Homing partSize = rand.NextPercent(1, .5); parts.Add(new ShipPartDNA() { PartType = SensorHoming.PARTTYPE, Position = new Point3D(0, 0, 2.5), Orientation = Quaternion.Identity, Scale = new Vector3D(partSize, partSize, partSize) }); // Vision //TODO: Support filtering by type partSize = rand.NextPercent(1, .5); parts.Add(new SensorVisionDNA() { PartType = SensorVision.PARTTYPE, Position = new Point3D(0, 0, 1.5), Orientation = Quaternion.Identity, Scale = new Vector3D(partSize, partSize, partSize), SearchRadius = itemOptions.VisionSensor_SearchRadius }); // Brains int numBrains = 1 + Convert.ToInt32(rand.NextPow(5, 1d) * 4); for (int cntr = 0; cntr < numBrains; cntr++) { partSize = rand.NextPercent(1, .5); Point3D position = new Point3D(0, 0, 0); if (numBrains > 1) { position = Math3D.GetRandomVector_Circular(1).ToPoint(); } parts.Add(new ShipPartDNA() { PartType = Brain.PARTTYPE, Position = position, Orientation = Quaternion.Identity, Scale = new Vector3D(partSize, partSize, partSize) }); } // MotionController - always exactly one of these partSize = rand.NextPercent(1, .5); parts.Add(new ShipPartDNA() { PartType = MotionController2.PARTTYPE, Position = new Point3D(0, 0, -1.5), Orientation = Quaternion.Identity, Scale = new Vector3D(partSize, partSize, partSize) }); // Store it bot.Parts = parts.ToArray(); #endregion if (shellColors == null) { bot.ShellColors = BotShellColorsDNA.GetRandomColors(); } else { bot.ShellColors = shellColors; } #region Weapon WeaponDNA weaponActual = null; if (weapon == null) { if (rand.NextDouble() < .95d) { WeaponHandleMaterial[] weaponMaterials = new WeaponHandleMaterial[] { WeaponHandleMaterial.Soft_Wood, WeaponHandleMaterial.Hard_Wood }; weaponActual = new WeaponDNA() { UniqueID = Guid.NewGuid(), Handle = WeaponHandleDNA.GetRandomDNA(weaponMaterials[StaticRandom.Next(weaponMaterials.Length)]) }; } } else { weaponActual = weapon; } #endregion return(bot, weaponActual); }
public OfflineWorld(double size, ItemOptionsArco itemOptions) { const int INTERVAL = 50; this.Size = size; _thread = new TimerCreateThread<WorldVars>(Prep, Tick, TearDown, itemOptions, size, INTERVAL); _thread.Interval = INTERVAL; _thread.Start(); }
private WorldVars Prep(params object[] args) { // Cast the args ItemOptionsArco itemOptions = (ItemOptionsArco)args[0]; double boundrySize = (double)args[1]; int interval = (int)args[2]; // Build the return object WorldVars retVal = new WorldVars(); #region Misc retVal.ItemOptions = itemOptions; retVal.Gravity = new GravityFieldUniform() { Gravity = new Vector3D(0, -retVal.ItemOptions.Gravity, 0) }; retVal.EditorOptions = new EditorOptions(); #endregion #region Init World double boundrySizeHalf = boundrySize / 2d; retVal.BoundryMin = new Point3D(-boundrySizeHalf, -boundrySizeHalf, -boundrySizeHalf); retVal.BoundryMax = new Point3D(boundrySizeHalf, boundrySizeHalf, boundrySizeHalf); retVal.World = new World(false); retVal.World.SetCollisionBoundry(retVal.BoundryMin, retVal.BoundryMax); #endregion #region Materials retVal.MaterialManager = new MaterialManager(retVal.World); retVal.MaterialIDs = new MaterialIDs(); // Wall Game.Newt.v2.NewtonDynamics.Material material = new Game.Newt.v2.NewtonDynamics.Material(); material.Elasticity = ItemOptionsArco.ELASTICITY_WALL; retVal.MaterialIDs.Wall = retVal.MaterialManager.AddMaterial(material); // Bot material = new Game.Newt.v2.NewtonDynamics.Material(); retVal.MaterialIDs.Bot = retVal.MaterialManager.AddMaterial(material); // Bot Ram material = new Game.Newt.v2.NewtonDynamics.Material(); material.Elasticity = ItemOptionsArco.ELASTICITY_BOTRAM; retVal.MaterialIDs.BotRam = retVal.MaterialManager.AddMaterial(material); // Exploding Bot material = new Game.Newt.v2.NewtonDynamics.Material(); material.IsCollidable = false; retVal.MaterialIDs.ExplodingBot = retVal.MaterialManager.AddMaterial(material); // Weapon material = new Game.Newt.v2.NewtonDynamics.Material(); retVal.MaterialIDs.Weapon = retVal.MaterialManager.AddMaterial(material); // Treasure Box material = new Game.Newt.v2.NewtonDynamics.Material(); retVal.MaterialIDs.TreasureBox = retVal.MaterialManager.AddMaterial(material); //// Collisions //_materialManager.RegisterCollisionEvent(_materialIDs.Bot, _materialIDs.Bot, Collision_BotBot); //_materialManager.RegisterCollisionEvent(_materialIDs.Bot, _materialIDs.Weapon, Collision_BotWeapon); //_materialManager.RegisterCollisionEvent(_materialIDs.Weapon, _materialIDs.Weapon, Collision_WeaponWeapon); ////_materialManager.RegisterCollisionEvent(_materialIDs.Bot, _materialIDs.Wall, Collision_BotWall); //_materialManager.RegisterCollisionEvent(_materialIDs.Weapon, _materialIDs.Wall, Collision_WeaponWall); //_materialManager.RegisterCollisionEvent(_materialIDs.Weapon, _materialIDs.TreasureBox, Collision_WeaponTreasureBox); //_materialManager.RegisterCollisionEvent(_materialIDs.Bot, _materialIDs.TreasureBox, Collision_BotTreasureBox); #endregion #region Map retVal.Map = new Map(null, null, retVal.World); retVal.Map.ShouldBuildSnapshots = true; #endregion #region Keep 2D //TODO: drag plane should either be a plane or a large cylinder, based on the current (level|scene|stage|area|arena|map|place|region|zone) // This game is 3D emulating 2D, so always have the mouse go to the XY plane retVal.DragPlane = new DragHitShape(); retVal.DragPlane.SetShape_Plane(new Triangle(new Point3D(-1, -1, 0), new Point3D(1, -1, 0), new Point3D(0, 1, 0))); // This will keep objects onto that plane using forces (not velocities) retVal.Keep2D = new KeepItems2D(); retVal.Keep2D.SnapShape = retVal.DragPlane; #endregion #region Update Manager retVal.UpdateManager = new UpdateManager( new Type[] { typeof(ArcBot), typeof(ArcBotNPC) }, new Type[] { typeof(ArcBot), typeof(ArcBotNPC) }, retVal.Map, interval); #endregion retVal.World.UnPause(); // Store this at the class level so that public methods can get access to it _vars = retVal; return(retVal); }