public async virtual Task <NascarEvent> SimulatePracticeAsync(NascarEvent raceEvent) { _lapTimeService = new LapTimeService(raceEvent.Track); NascarPracticeRun p1 = raceEvent.Runs.OfType <NascarPracticeRun>().FirstOrDefault(r => r.RunType == NascarRunType.Practice1); if (p1 != null) { p1.Vehicles = raceEvent.Vehicles; SimulatePracticeRun(p1); PopulateResults(p1); } NascarPracticeRun p2 = raceEvent.Runs.OfType <NascarPracticeRun>().FirstOrDefault(r => r.RunType == NascarRunType.Practice2); if (p2 != null) { p2.Vehicles.Clear(); p2.Vehicles = raceEvent.Vehicles; SimulatePracticeRun(p2); PopulateResults(p2); } NascarPracticeRun p3 = raceEvent.Runs.OfType <NascarPracticeRun>().FirstOrDefault(r => r.RunType == NascarRunType.FinalPractice); if (p3 != null) { p3.Vehicles.Clear();; p3.Vehicles = raceEvent.Vehicles; SimulatePracticeRun(p3); PopulateResults(p3); } return(await Task.FromResult(raceEvent)); }
public async virtual Task <NascarEvent> SimulateQualifyingAsync(NascarEvent raceEvent) { _lapTimeService = new LapTimeService(raceEvent.Track); NascarQualifyingRun q1 = raceEvent.Runs.OfType <NascarQualifyingRun>().FirstOrDefault(r => r.RunType == NascarRunType.QualifyingStage1); if (q1 != null) { q1.Vehicles = raceEvent.Vehicles; SimulateQualifyingRun(q1); PopulateResults(q1, raceEvent.Series.QualifyingRound1Count.Value); } NascarQualifyingRun q2 = raceEvent.Runs.OfType <NascarQualifyingRun>().FirstOrDefault(r => r.RunType == NascarRunType.QualifyingStage2); if (q2 != null) { q2.Vehicles.Clear(); foreach (QualifyingResult result in q1.Results.OrderBy(r => r.Position).Take(raceEvent.Series.QualifyingRound2Count.Value)) { q2.Vehicles.Add(new NascarVehicle() { DriverId = result.DriverId, VehicleId = result.VehicleId }); } SimulateQualifyingRun(q2); PopulateResults(q2, raceEvent.Series.QualifyingRound2Count.Value); } NascarQualifyingRun q3 = raceEvent.Runs.OfType <NascarQualifyingRun>().FirstOrDefault(r => r.RunType == NascarRunType.FinalQualifyingStage); if (q3 != null) { q3.Vehicles.Clear(); foreach (QualifyingResult result in q2.Results.OrderBy(r => r.Position).Take(raceEvent.Series.QualifyingFinalRoundCount)) { q3.Vehicles.Add(new NascarVehicle() { DriverId = result.DriverId, VehicleId = result.VehicleId }); } SimulateQualifyingRun(q3); PopulateResults(q3, raceEvent.Series.QualifyingFinalRoundCount); } ((List <QualifyingResult>)raceEvent.QualifyingResults).AddRange(q1.Results.OrderBy(r => r.Position).Skip(raceEvent.Series.QualifyingRound2Count.Value)); ((List <QualifyingResult>)raceEvent.QualifyingResults).AddRange(q2.Results.OrderBy(r => r.Position).Skip(raceEvent.Series.QualifyingFinalRoundCount)); ((List <QualifyingResult>)raceEvent.QualifyingResults).AddRange(q3.Results.OrderBy(r => r.Position).Take(raceEvent.Series.QualifyingRound1Count.Value)); PrintQualifyingResults(raceEvent); return(await Task.FromResult(raceEvent)); }
public async virtual Task <NascarEvent> SimulateRaceAsync(NascarEvent raceEvent) { _lapTimeService = new LapTimeService(raceEvent.Track); _vehicleLapService = new VehicleLapService2(_lapTimeService); StateService.Initialize(); int cautionLapsRemaining = 0; int greenWhiteCheckeredLapCount = 2; int endOfStageCautionLapCount = 5; int pitsClosedBeforeStageEndLaps = 2; int nextStageEndLap = 0; int currentStageIndex = 0; int lapsRunUnderThisCaution = 0; bool pitsAreOpen = true; bool leadLapPitOnly = false; bool isFirstCautionLap = true; List <int> stageEndLaps = GetStageEndLaps(raceEvent); nextStageEndLap = stageEndLaps[currentStageIndex]; var firstStage = raceEvent.Runs.OfType <NascarRaceRun>().Where(r => r.RunType == NascarRunType.RaceStage1).SingleOrDefault(); var secondStage = raceEvent.Runs.OfType <NascarRaceRun>().Where(r => r.RunType == NascarRunType.RaceStage2).SingleOrDefault(); var finalStage = raceEvent.Runs.OfType <NascarRaceRun>().Where(r => r.RunType == NascarRunType.FinalRaceStage).SingleOrDefault(); NascarRaceRun run = firstStage; int advertisedRaceEndLap = finalStage.EndLap; int actualRaceEndLap = advertisedRaceEndLap; List <NascarRaceLap> raceLaps = _vehicleLapService.GetStartingLineup(raceEvent); List <NascarRaceLap> laps = new List <NascarRaceLap>(); StateService.GreenFlagOn(); for (int lapNumber = 1; lapNumber <= actualRaceEndLap; lapNumber++) { //***** random caution generator *****// if (!StateService.IsCaution) { var randomCautionResult = _cautionService.GetRandomCautionResult(); var isCaution = randomCautionResult.IsCaution; if (isCaution) { var caution = new NascarCautionSegment() { StartLap = lapNumber }; raceEvent.Cautions.Add(caution); isFirstCautionLap = true; StateService.CautionOn(); if (StateService.IsWhiteFlag) { cautionLapsRemaining = 1; } else { cautionLapsRemaining = randomCautionResult.CautionLaps; pitsAreOpen = false; } } } else { isFirstCautionLap = false; if (!pitsAreOpen && lapsRunUnderThisCaution > 0 && (lapNumber + pitsClosedBeforeStageEndLaps <= nextStageEndLap)) { pitsAreOpen = true; leadLapPitOnly = true; } else if (pitsAreOpen) { leadLapPitOnly = false; } } //***** end of race *****// if (lapNumber == actualRaceEndLap - 1) { StateService.WhiteFlagOn(); } else if (lapNumber == actualRaceEndLap) { StateService.CheckeredFlagOn(); } //***** end of stage *****// if (run.RunType != NascarRunType.FinalRaceStage) { if (lapNumber + pitsClosedBeforeStageEndLaps == nextStageEndLap) { // end of stage pitsAreOpen = false; } else if (lapNumber == nextStageEndLap) { // end of stage StateService.EndOfStageOn(); cautionLapsRemaining = endOfStageCautionLapCount; var caution = new NascarCautionSegment() { StartLap = lapNumber }; raceEvent.Cautions.Add(caution); isFirstCautionLap = true; currentStageIndex++; if (currentStageIndex == 1) { if (currentStageIndex < stageEndLaps.Count) { nextStageEndLap = stageEndLaps[currentStageIndex]; run = secondStage; } else { currentStageIndex++; } } leadLapPitOnly = (pitsAreOpen && lapsRunUnderThisCaution <= 2); pitsAreOpen = (lapsRunUnderThisCaution > 0); if (currentStageIndex == 2) { run = finalStage; nextStageEndLap = finalStage.EndLap; } } } //***** overdrive *****// if (StateService.IsCaution && !StateService.IsWhiteFlag && lapNumber + cautionLapsRemaining >= actualRaceEndLap) { // end of race extended by caution StateService.OverdriveOn(); actualRaceEndLap = (lapNumber + cautionLapsRemaining + greenWhiteCheckeredLapCount); } //***** end of caution *****// if (StateService.IsCaution && cautionLapsRemaining == 0) { // end of caution, back to green StateService.GreenFlagOn(); lapsRunUnderThisCaution = 0; raceEvent.Cautions.LastOrDefault().EndLap = lapNumber; var luckyDog = raceLaps.FirstOrDefault(l => l.IsLuckyDog); if (luckyDog != null) { luckyDog.IsLuckyDog = false; } } // vehicle pit stops if (pitsAreOpen) { raceLaps = SetPitStops(raceLaps, raceEvent.Track.PitWindow, StateService.IsCaution, leadLapPitOnly); } // vehicle lap times if (StateService.IsGreenFlag) { laps = _vehicleLapService.UpdateRaceLaps(raceLaps, LapState.GreenFlag); } else if (StateService.IsCaution) { if (isFirstCautionLap) { laps = _vehicleLapService.UpdateRaceLaps(raceLaps, LapState.CautionFlag); } else if (cautionLapsRemaining == 1) { laps = _vehicleLapService.UpdateRaceLaps(raceLaps, LapState.OneToGreenFlag); } else { laps = _vehicleLapService.UpdateRaceLaps(raceLaps, LapState.CautionFlag); } } ((List <NascarRaceLap>)run.Laps).AddRange(laps.ToList()); raceLaps.Clear(); raceLaps.AddRange(laps); laps.Clear(); if (StateService.IsCaution) { cautionLapsRemaining--; lapsRunUnderThisCaution++; } Console.WriteLine($"Lap {lapNumber} [{StateService.State.ToString()}] "); } return(await Task.FromResult(raceEvent)); }