/// <summary> /// Calculates visits for each household based on reputation. /// </summary> protected virtual void CalculateVisitsFromHouseholds(List <double> cumulativeReputation, double totalReputation) { for (int i = 0; i < Settlement.NumHouseholds; i++) { Household thisHousehold = Settlement.GetHouseholdAtIndex(i); //Do they eat out? if (!thisHousehold.EatsOut()) { continue; } //Yes, they do, but where? Calculate based on nearest outlet and reputation. double randomRepNum = Random.NextDouble() * totalReputation; int current = 0; while (current < cumulativeReputation.Count) { //Is this company's reputation sufficient for this household to eat there? if (randomRepNum < cumulativeReputation[current]) { //Yes, eat then break. Companies[current].AddVisitToNearestOutlet(thisHousehold.Position, ref visits); break; } current++; } } }
/// <summary> /// Calculates visits from households based on both reputation AND distance AND type of company. /// </summary> protected override void CalculateVisitsFromHouseholds(List <double> cumulativeReputation, double totalReputation) { for (int i = 0; i < Settlement.NumHouseholds; i++) { Household thisHouse = Settlement.GetHouseholdAtIndex(i); //Does this household eat out? if (!thisHouse.EatsOut()) { continue; } //Pick a type of restaurant to eat at. CompanyType picked = PickRestaurantType(); //Get outlets within a set boundary, of the selected type. double radius; switch (picked) { case CompanyType.Family: radius = Settings.Get.BalancedSim_TravelRadiusFamily; break; case CompanyType.FastFood: radius = Settings.Get.BalancedSim_TravelRadiusFastFood; break; case CompanyType.NamedChef: radius = Settings.Get.BalancedSim_TravelRadiusNamedChef; break; default: //Unknown company type. throw new Exception("Unknown company type to set travel radius for. Please update method."); } List <Outlet> outletsToPick = GetOutletsAround(thisHouse.Position, radius).Where(x => x.ParentCompany.Type == picked).ToList(); //Are there any outlets to visit? if (outletsToPick.Count == 0) { //Register a failed event. EventChain.AddEvent(new FailedToEatOutEvent() { Origin = thisHouse.Position, Radius = radius, OutletType = picked }); //This house is now done. continue; } //Get the companies that these outlets have. List <Company> companiesNearMe = new List <Company>(); foreach (var outlet in outletsToPick) { if (companiesNearMe.FindIndex(x => x.Name == outlet.ParentCompany.Name) == -1) { companiesNearMe.Add(outlet.ParentCompany); } } //Randomly roll on their reputation. double totalRep = companiesNearMe.Sum(x => x.Reputation); List <double> cumulativeRep = companiesNearMe.Select(x => x.Reputation).CumulativeSum().ToList(); double randomSelection = Random.NextDouble() * totalRep; Company selected = null; for (int k = 0; k < cumulativeRep.Count; k++) { if (randomSelection < cumulativeRep[k]) { selected = companiesNearMe[k]; break; } } //Successfully selected a company, visit! selected.AddVisitToNearestOutlet(thisHouse.Position, ref base.visits); } }