public void Run(bool verbose = false) { for (var i = 0; i < _t / 2; i++) { var tram1 = new Tram(_route1) { StartWaiting = _time }; var tram2 = new Tram(_route2) { StartWaiting = _time }; _trams.Add(tram1); _trams.Add(tram2); if (i == 0) { ScheduleEvent(new TramStartEvent(_route1NextStart), tram1); ScheduleEvent(new TramStartEvent(_route2NextStart), tram2); } else { ScheduleEvent(new TramEstimatedStartEvent(_route1NextStart), tram1); ScheduleEvent(new TramEstimatedStartEvent(_route2NextStart), tram2); } _route1NextStart += 60 / _f * 60; _route2NextStart += 60 / _f * 60; } for (var i = 0; i < _trams.Count; i++) { _trams[i].Index = i; _trams[i].Ahead = _trams[(_trams.Count + i - 2) % _trams.Count]; _trams[i].Behind = _trams[(i + 2) % _trams.Count]; } _ridesRoute1 = 1; _ridesRoute2 = 1; var nextEvent = GetNextEvent(); while (nextEvent.Event.TimeStamp < _maxTime) { _time = nextEvent.Event.TimeStamp; var tram = nextEvent.Target as Tram; if (tram != null) { Operate(tram, nextEvent.Event, verbose); } var tramstop = nextEvent.Target as TramStop; if (tramstop != null) { tramstop.ApplyChange(nextEvent.Event, verbose); switch (nextEvent.Event.Name) { case PassengerArrivalEvent.Name: _passengers.Add(tramstop.Passengers.Last()); ScheduleNewArrivalEvent(tramstop); break; case ArrivalRateChangeEvent.Name: if (!tramstop.GeneratingEvents) { ScheduleNewArrivalEvent(tramstop); } break; } } nextEvent = GetNextEvent(); } }
private void Operate(Tram tram, Event @event, bool verbose = false) { tram.ApplyChange(@event, verbose); switch (@event.Name) { case TramEstimatedStartEvent.Name: if (tram.DeltaT > 0 && !tram.Behind.Waiting) { ScheduleEvent(new TramEstimatedStartEvent(_time + tram.DeltaT), tram); } else { if (tram.Destination == _route1) { _delaysRoute1.Add(_time - (_ridesRoute1++ *(60 / _f * 60))); var removed = _route2End.Occupied.Remove(tram); var toStart = _route2End.Occupied.Where(t => t.Waiting).FirstOrDefault(); if (toStart != null && removed && _eventList.Where(e => e.Event.GetType() == typeof(TramChangeTrackEvent) && e.Target == toStart).Count() == 0) { ScheduleEvent(new TramChangeTrackEvent(_time + 40, _route1), toStart); } } else if (tram.Destination == _route2) { _delaysRoute2.Add(_time - (_ridesRoute2++ *(60 / _f * 60))); var removed = _route1End.Occupied.Remove(tram); var toStart = _route1End.Occupied.Where(t => t.Waiting).FirstOrDefault(); if (toStart != null && removed && _eventList.Where(e => e.Event.GetType() == typeof(TramChangeTrackEvent) && e.Target == toStart).Count() == 0) { ScheduleEvent(new TramChangeTrackEvent(_time + 40, _route2), toStart); } } //Should probably schedule TramEstimatedStop. ScheduleEvent(new TramStartEvent(_time), tram); } break; //Might be redundant. case TramStartEvent.Name: ScheduleEvent(new TramStopEvent(_time + tram.DeltaT), tram); if (tram.Behind.Waiting && !tram.Behind.AtEndPoint) { ScheduleEvent(new TramEstimatedStartEvent(_time + 40), tram.Behind); } break; case TramStopEvent.Name: if (!tram.Waiting) { if (tram.AtEndPoint && _eventList.Where(e => e.Event.GetType() == typeof(TramChangeTrackEvent) && e.Target == tram).Count() == 0) { ScheduleEvent(new TramChangeTrackEvent(_time + tram.DeltaT, tram.Route == 1 ? _route2 : _route1), tram); } else { ScheduleEvent(new TramEstimatedStartEvent(_time + tram.DeltaT), tram); } } break; case TramChangeTrackEvent.Name: if (tram.Route == 1 && _route1NextStart < _time + _q || tram.Route == 2 && _route2NextStart < _time + _q) { ScheduleEvent(new TramEstimatedStartEvent(_time + _q), tram); } else { tram.StartWaiting = _time; ScheduleEvent(new TramEstimatedStartEvent(tram.Route == 1 ? _route1NextStart : _route2NextStart), tram); } if (tram.Route == 1) { _route1NextStart += 60 / _f * 60; } else { _route2NextStart += 60 / _f * 60; } break; } }