private Task NextStepAsync(CancellationToken ct = default(CancellationToken)) { return(Task.Run(() => { SimulationEventArgs args = new SimulationEventArgs(); _environment.IncreaseYear(); args.CurrentYear = _environment.Year; //new population size int peopleCount = (int)Math.Round(_settings.PopulationSize * Math.Pow(_populationFactor, _environment.Year)); var newPopulation = new Person[peopleCount]; //main loop int currentPopulationSize = 0; foreach (var person in _persons) { ct.ThrowIfCancellationRequested(); ++currentPopulationSize; if (currentPopulationSize > peopleCount) { break; } if (person == null) { continue; } Person child; if (!Process(person, args, out child)) { continue; } PutPerson(person, newPopulation); if (child != null) { ++currentPopulationSize; if (currentPopulationSize > peopleCount) { break; } PutPerson(child, newPopulation); } } _persons = newPopulation; SimulationEvent(this, args); }, ct)); }
private bool Process(Person person, SimulationEventArgs args, out Person child) { child = null; //if too old if (person.Age >= _settings.LifeLimit) { ++args.NaturalDeathCount; return(false); } //if man if (person.Sex == Sex.Man) { return(true); } //if not pregnant var pregoInfo = _settings.GetPregoInfo(person.Age); if (pregoInfo == null) { return(true); } //get father var father = SearchNubilityMan(); //get child BornInfo bornInfo; if (!args.BornInfos.TryGetValue(pregoInfo.Order, out bornInfo)) { bornInfo = new BornInfo { Order = pregoInfo.Order, MotherAge = person.Age }; args.BornInfos.Add(bornInfo.Order, bornInfo); } child = GenerateChild(father, person, pregoInfo.Factor); if (child == null) { ++bornInfo.DeathCount; return(false); } ++bornInfo.BornCount; return(true); }