public void Setup() { // Note: This method has poor cohesion. Without changing functionality, we will refactor this method in class to improve cohesion SetupDefaults(); SetupSensors(); CreateRaceGroups(); // Setup race groups foreach (RaceGroup group in groups) { group.Setup(); } // Setup a 1 cheater in each group for (int raceGroupA = 0; raceGroupA < groups.Count - 1; raceGroupA++) { int raceGroupB = raceGroupA + 1; int cheaterIndex1 = RandomChooser.ChooseInt(0, groups[raceGroupA].Count); Racer cheater1 = groups[raceGroupA][cheaterIndex1]; int cheaterIndex2 = RandomChooser.ChooseInt(0, groups[raceGroupB].Count); Racer cheater2 = groups[raceGroupB][cheaterIndex2]; cheater1.WillTryToCheatWith = cheater2; cheater2.WillTryToCheatWith = cheater1; } // Compute race times messagesToSend = new List <RacerStatus>(); double previousMilageMarker = 0; for (int sensorIndex = 0; sensorIndex < sensors.Count; sensorIndex++) { Sensor sensor = sensors[sensorIndex]; double deltaMilage = sensor.MileMarker - previousMilageMarker; foreach (RaceGroup group in groups) { for (int i = 0; i < group.Count; i++) { Racer racer = group[i]; if (racer.Time == 0) { racer.Time = group.StartTime; } double speed = racer.RelativeSpeed + group.AverageSpeed; racer.Time += Convert.ToInt32(60 * 60 * 1000 * deltaMilage / speed); } } // Converge cheaters foreach (RaceGroup group in groups) { foreach (Racer racer in group) { if (racer.WillTryToCheatWith != null) { int averageTime = (racer.Time + racer.WillTryToCheatWith.Time) / 2; int delta = averageTime - racer.Time; racer.Time += delta / 2; } } } // Create race status object foreach (RaceGroup group in groups) { foreach (Racer racer in group) { RacerStatus status = new RacerStatus() { SensorId = sensor.Id, RacerBibNumber = racer.RaceBibNumber, Timestamp = racer.Time }; sensor.RacerTimes.Add(status); messagesToSend.Add(status); } } previousMilageMarker = sensor.MileMarker; } messagesToSend.Sort(delegate(RacerStatus x, RacerStatus y) { if (x.Timestamp < y.Timestamp) { return(-1); } else if (x.Timestamp > y.Timestamp) { return(1); } return(0); }); }