Пример #1
0
        public List <NascarRaceLap> GetStartingLineup(NascarEvent raceEvent)
        {
            NascarRaceRun stage1 = raceEvent
                                   .Runs
                                   .OfType <NascarRaceRun>()
                                   .FirstOrDefault(r => r.RunType == NascarRunType.RaceStage1);

            return(StartingLineup(raceEvent, stage1));
        }
Пример #2
0
        protected virtual List <NascarRaceLap> StartingLineup(NascarEvent raceEvent, NascarRaceRun stage1)
        {
            List <NascarRaceLap> raceLaps = new List <NascarRaceLap>();
            int    position        = 1;
            double leaderTotalTime = 0;

            foreach (QualifyingResult vehicle in raceEvent.QualifyingResults.OrderBy(q => q.Position))
            {
                vehicle.Position = position;

                double deltaRow = 0.5;

                double deltaNext = vehicle.Position == 1 ? 0 : (vehicle.Position % 2) == 0 ? 0.0 : 0.5;

                double deltaLeader = vehicle.Position <= 2 ? 0 : Math.Round((double)((vehicle.Position - 1) / 2), 0) * deltaRow;

                var newLap = new NascarRaceLap()
                {
                    Position             = vehicle.Position,
                    VehicleId            = vehicle.VehicleId,
                    DriverId             = vehicle.DriverId,
                    LapNumber            = 0,
                    LeaderLap            = 0,
                    Delta                = Math.Round(deltaNext, 3),
                    DeltaLeader          = Math.Round(deltaLeader, 3),
                    DeltaTravelledLeader = Math.Round(deltaLeader, 3),
                    LapSpeed             = 0,
                    LapTime              = 0,
                    TotalTime            = 0
                };

                raceLaps.Add(newLap);

                if (leaderTotalTime == 0)
                {
                    leaderTotalTime = newLap.TotalTime;
                }

                position++;
            }

            Console.WriteLine("Starting Lineup");

            PrintStandings(raceLaps, LapState.OneToGreenFlag);

            return(raceLaps);
        }
Пример #3
0
        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));
        }