private void RePopulate() { FoodObjs.Clear(); var creatures = AllGameObjs.OfType <Creature>().ToArray(); var minLifeSpan = creatures.Min(c => c.Lifespan); var indvdls = creatures .Select(c => c.Brain.Net.ToIndividual((c.Lifespan - minLifeSpan) + (c.Health / Creature.IdleHealthLossPerSecond / 2f))); var res = GeneticAlgorithm.Apply(indvdls).ToArray(); var rand = ThreadSafeRandom.Instance; for (int i = 0; i < creatures.Length; i++) { var nw = creatures[i].Brain.Net.SetWeights(res[i]); var @new = new Creature(this, Game.Res, GeomHelper.RandomPointInCircel(rand, WorldSize), initNw: nw); CreatureObjs[i] = @new; } var lastHist = GeneticAlgorithm.History.Last(); StatusStr = $"LF: {creatures.Min(c => c.Lifespan)} : {creatures.Max(c => c.Lifespan)} : {creatures.Average(c => c.Lifespan)}"; StatusStr += $"\nVar={lastHist.Variety} Gen#={lastHist.GenCount}"; StatusStr += $"\nElit={lastHist.UsedParams.ElitismFraction} Mut={lastHist.UsedParams.MutationFraction}"; }
public void Update(MouseState mState, KeyboardState kState, Point mPosInWorld, float secsPassed) { ActiveGameObjs = AllGameObjs.Where(go => go.Active).ToArray(); Parallel.ForEach(ActiveGameObjs, c => c.Move(secsPassed)); Parallel.ForEach(ActiveGameObjs, c => c.Interact(secsPassed)); WorldTotalTimeSec += secsPassed; if (WorldTotalTimeSec > MaxWorldTimeSec || ActiveGameObjs.OfType <Creature>().Count() == 0) { RePopulate(); WorldTotalTimeSec = 0; } FoodObjs.RemoveAll(f => !f.Active); var shortage = (ActiveGameObjs.OfType <Creature>().Count() * FoodToCreatureRatio) - FoodObjs.Count; var rand = ThreadSafeRandom.Instance; for (int i = 0; i < shortage; i++) { var @new = new Food(this, Game.Res, GeomHelper.RandomPointInCircel(rand, WorldSize)); FoodObjs.Add(@new); } }