private void UpdateSituation(TrafficSegmentConfiguration configuration) { _configuration = configuration; ResetToNormal(); MaxSpeed = configuration.MaxSpeed; MinSpeed = configuration.MinSpeed; AverageCarsPerMinute = configuration.AverageCarsPerMinute; SpeedingPercentage = configuration.SpeedingPercentage; SpeedLimit = configuration.SpeedLimit; RushHours = configuration.RushHours; _currentEvent = EventType.None; _currentTrend = TrafficTrend.None; }
public void Resimulate(Random random) { // Check rush hour (busy or finished) if (IsRushHour(SimulatedClock.Time, out var currentRushHour)) { AverageCarsPerMinute += random.Next(0, 10); try { var rushHourEvolution = (currentRushHour.TimeLeft(SimulatedClock.Time).TotalSeconds / currentRushHour.Duration.TotalSeconds); _currentTrend = rushHourEvolution < 0.80 ? TrafficTrend.Congesting : TrafficTrend.Clearing; } catch (DivideByZeroException) { _currentTrend = TrafficTrend.Clearing; } // First 80% of the timeframe, rushhour congestion, then clearing _currentEvent = EventType.RushHour; } else { if (_currentEvent == EventType.RushHour) { // Rushhour done , so reset to normal! ResetToNormal(); } } if (_currentEvent == EventType.None) { // Apply random small changes AverageCarsPerMinute += random.Next(-2, 3); SpeedingPercentage = _configuration.SpeedingPercentage + random.Next(-1, 2); MinSpeed = _configuration.MinSpeed + random.Next(-5, 6); MaxSpeed = _configuration.MaxSpeed + random.Next(-3, 4); AverageSpeed = _configuration.SpeedLimit - random.Next(2, 10); // Allow to cause an accident if (random.Next(0, 2000) == 0) { _currentEvent = EventType.Accident; _currentEventStartTime = SimulatedClock.Time; _eventLength = TimeSpan.FromMinutes(random.Next(15, 75)); } } // Apply accident logic if (_currentEvent == EventType.Accident) { if (_currentEventStartTime.Add(_eventLength) <= SimulatedClock.Time) { _currentEvent = EventType.None; ResetToNormal(); } // Apply random small changes AverageCarsPerMinute += random.Next(-2, 3); try { var accidentEvolution = ((SimulatedClock.Time - _currentEventStartTime).TotalSeconds / _eventLength.TotalSeconds); _currentTrend = accidentEvolution < 0.88 ? TrafficTrend.Congesting : TrafficTrend.Clearing; } catch (DivideByZeroException) { _currentTrend = TrafficTrend.Clearing; } _currentEvent = EventType.RushHour; } switch (_currentTrend) { case TrafficTrend.Clearing: AverageSpeed += random.Next(2, 10); break; case TrafficTrend.Congesting: AverageSpeed -= random.Next(2, 10); break; } GuardValues(); }