//Mutates the Brain public static Brain.DataInput MutateWeights(Brain.DataInput data, float mutationFactor) { data.LEFOw.LTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.LEFOw.RTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.LEFOw.MTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.REFOw.LTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.REFOw.RTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.REFOw.MTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.LEPOw.LTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.LEPOw.RTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.LEPOw.MTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.REPOw.LTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.REPOw.RTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.REPOw.MTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.HEALTHw.LTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.HEALTHw.RTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.HEALTHw.MTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.CLOCKw.LTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.CLOCKw.RTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; data.CLOCKw.MTHR += (float)((Program.game.rnd.NextDouble() * 2) - 1) * mutationFactor; return(data); }
//Constructor public Creature(Vector2 location, float rotation, Color color, Brain.DataInput weights = null, int size = 50) { this.Location = location; this.Rotation = rotation; this.Color = color; this.Size = size; this.Health = 1; this.Brain = new Brain.Brain(); if (weights == null) { this.Weights = Brain.GenerateRandomWeights(); } else { this.Weights = weights; } }
//Update loop, called by manager public void Update(GameTime gameTime, Rectangle Bounds) { //Update Position and Rotation this.Rotation = this.Rotation + (float)(this.TurningVelocity * gameTime.ElapsedGameTime.TotalMilliseconds * Program.game.simulationSpeed); this.Location = new Vector2( (float)(this.Location.X + Math.Cos(this.Rotation) * (this.Velocity * gameTime.ElapsedGameTime.TotalMilliseconds * Program.game.simulationSpeed)), (float)(this.Location.Y + Math.Sin(this.Rotation) * (this.Velocity * gameTime.ElapsedGameTime.TotalMilliseconds * Program.game.simulationSpeed)) ); //Check for border collision if (this.Location.Y <= 0) { this.Location.Y = Bounds.Height - 1; } if (this.Location.Y >= Bounds.Height) { this.Location.Y = 1; } if (this.Location.X <= 0) { this.Location.X = Bounds.Width - 1; } if (this.Location.X >= Bounds.Width) { this.Location.X = 1; } //Calculate Field of view data Vector2 FOVcenterEnd = new Vector2((float)(Math.Cos(this.Rotation) * Managers.CreatureManager.LineDirectionLength) + this.Location.X, (float)(Math.Sin(this.Rotation) * Managers.CreatureManager.LineDirectionLength) + this.Location.Y); Vector2 FOVrightEnd = new Vector2((float)(Math.Cos(this.Rotation + Managers.CreatureManager.eyeAngle) * Managers.CreatureManager.LineEyeLength) + this.Location.X, (float)(Math.Sin(this.Rotation + Managers.CreatureManager.eyeAngle) * Managers.CreatureManager.LineEyeLength) + this.Location.Y); Vector2 FOVleftEnd = new Vector2((float)(Math.Cos(this.Rotation - Managers.CreatureManager.eyeAngle) * Managers.CreatureManager.LineEyeLength) + this.Location.X, (float)(Math.Sin(this.Rotation - Managers.CreatureManager.eyeAngle) * Managers.CreatureManager.LineEyeLength) + this.Location.Y); //Check for food in field of view int pointsInLE = 0; int pointsInRE = 0; foreach (Food food in Managers.FoodManager.foods) { if (PointInTriangle(food.Location, this.Location, FOVcenterEnd, FOVleftEnd)) { pointsInLE++; } if (PointInTriangle(food.Location, this.Location, FOVcenterEnd, FOVrightEnd)) { pointsInRE++; } } if (pointsInLE > 1) { pointsInLE = 1; } if (pointsInLE < 0) { pointsInLE = 0; } if (pointsInRE > 1) { pointsInRE = 1; } if (pointsInRE < 0) { pointsInRE = 0; } //Check for poison in field of view float poiPointsInLE = 0; float poiPointsInRE = 0; foreach (Poison poison in Managers.PoisonManager.poisons) { if (PointInTriangle(poison.Location, this.Location, FOVcenterEnd, FOVleftEnd)) { poiPointsInLE++; } if (PointInTriangle(poison.Location, this.Location, FOVcenterEnd, FOVrightEnd)) { poiPointsInRE++; } } if (poiPointsInLE > 1) { poiPointsInLE = 1; } if (poiPointsInLE < 0) { poiPointsInLE = 0; } if (poiPointsInRE > 1) { poiPointsInRE = 1; } if (poiPointsInRE < 0) { poiPointsInRE = 0; } //Process data Brain.DataInput dataToProcess = new Brain.DataInput() { LEFO = pointsInLE, REFO = pointsInRE, LEPO = poiPointsInLE, REPO = poiPointsInRE, HEALTH = this.Health, CLOCK = this.Clock, LEFOw = this.Weights.LEFOw, REFOw = this.Weights.REFOw, LEPOw = this.Weights.LEPOw, REPOw = this.Weights.REPOw, HEALTHw = this.Weights.HEALTHw, CLOCKw = this.Weights.CLOCKw }; Brain.DataOutput thrusts = Brain.ProcessData(dataToProcess); //Move this.Push(PushDirection.Middle, thrusts.MTHR); this.Push(PushDirection.TurnLeft, thrusts.LTHR / 50); this.Push(PushDirection.TurnRight, thrusts.RTHR / 50); //Update attributes this.Velocity *= frictionFactor; this.TurningVelocity *= frictionFactorTurning; this.Health -= (float)0.0008; this.Color.A = Convert.ToByte(255 - (255 - (this.Health * 255))); this.Clock = (float)(Math.Sin(gameTime.TotalGameTime.TotalMilliseconds * Program.game.simulationSpeed / 50) + 1) / 2; this.Age += (1 * Program.game.simulationSpeed); }