/// <summary> /// Tries to finds all possible mating partners in all available animals. /// When a male and female is matched, they are removed from the collections of available animals. /// </summary> /// <param name="availableMales">Collection which keeps available males</param> /// <param name="availableFemales">Collection which keeps available females</param> /// <returns>Returns Task object which represents an asynchronous operation</returns> public async Task HandleAvailableAnimals(ConcurrentBag <IMale> availableMales, ConcurrentBag <IFemale> availableFemales) { var tasks = new List <Task>(); var tuples = new List <Tuple <IFemale, IMale> >(); IFemale female = null; IMale male = null; while (availableFemales.TryTake(out female)) { if (!female.IsAlive) // check for alive females, dead animals will be removed from simulation collections. { continue; } male = null; while (availableMales.TryTake(out male)) { if (!male.IsAlive) // check for alive males, dead animals will be removed from simulation collections. { continue; } tuples.Add(new Tuple <IFemale, IMale>(female, male)); break; } if (male == null) { // add female back to available females availableFemales.Add(female); break; } } // handles the list of "male and female couples to mate" by grouping // predefined number of the couples together and routing them to be handled by a new asynchronous Task for (int i = 0; i < tuples.Count; i += App.SimulationConfig.OperationCountPerTask) { tasks.Add(simulationEventHandler.OnMatingPartnersFound(tuples.GetRange(i, Math.Min(App.SimulationConfig.OperationCountPerTask, tuples.Count - i)))); } // Waits for all the asynchronous tasks to be completed in order to proceed. // This is important for the simulation execution in order not to bypass any operation which may cause wrong simulation results. await Task.WhenAll(tasks.ToArray()); }
/// <summary> /// Determines if the mating will succeed with result of female pregnancy. /// Current implementation provides 50% pregnancy chance. /// </summary> /// <param name="female">female to mate</param> /// <param name="male">male to mate</param> /// <returns>Returns true if female gets pregnant otherwise returns false</returns> public bool Mate(IFemale female, IMale male) { // Future Scope: // Fertality rates can be added to male and female through configuration for pregnancy probability. return(random.Value.Next(0, 2) == 0); }