public void HandleExpectedDeparture(object sender, TransportArgs e) { e.FromStation.CurrentTram = null; var delayAtStation = 0; var switchDelay = 0; if (e.ToStation.IsTerminal && e.FromStation != e.ToStation) { switchDelay = e.ToStation.SwitchDelay(e.TriggerTime); } if (e.ToStation.TimeOfLastTram.HasValue) { delayAtStation = (e.ToStation.TimeOfLastTram.Value + MinimumTimeBetweenTrains) - e.TriggerTime; } TotalDelay += Math.Max(switchDelay, delayAtStation); EventQueue.Add(new TransportArgs() { FromStation = e.FromStation, Tram = e.Tram, ToStation = e.ToStation, TriggerTime = e.TriggerTime + Math.Max(switchDelay, delayAtStation), Type = TransportArgsType.Departure }); }
private void HandleDeparture(object sender, TransportArgs e) { e.FromStation.CurrentTram = null; e.Tram.CurrentStation = null; e.FromStation.TimeOfLastTram = e.TriggerTime; var tramDepartureFromTerminal = e.Tram.DepartureFromPreviousTerminal; //Remember when the tram departed from the terminal //to know in which timetable cycle it should arrive if (e.FromStation.IsTerminal) { if (tramDepartureFromTerminal != int.MinValue) { var nextDepartureTime = e.FromStation.Timetable.GetNextDepartureTime(tramDepartureFromTerminal); if (nextDepartureTime == null) { return; } var dep = nextDepartureTime.Value; //mark departure time as used e.FromStation.Timetable[dep] = 0; } e.Tram.PreviousTerminal = e.FromStation; e.Tram.DepartureFromPreviousTerminal = e.TriggerTime; e.Tram.IsDirectionToCentraal = Track.GetPR() == e.FromStation; } //if there are any trams that need to arrive at the station then do it. if (e.FromStation.TramsQueue.Count > 0) { EventQueue.Add(new TransportArgs() { //assume it happens instantly Tram = e.FromStation.TramsQueue.Dequeue(), FromStation = e.Tram.LastActiveStation, ToStation = e.FromStation, TriggerTime = e.TriggerTime, Type = TransportArgsType.Arrival }); } // upon departure schedule an arrival EventQueue.Add(new TransportArgs() { FromStation = e.FromStation, ToStation = e.ToStation, TriggerTime = e.TriggerTime + GetTravelTime(e.FromStation, e.ToStation), Tram = e.Tram, Type = TransportArgsType.ExpectedArrival }); }
public void HandleExpectedArrival(object sender, TransportArgs e) { e.Tram.CurrentStation = e.ToStation; if (e.ToStation.CurrentTram == null) { EventQueue.Add(new TransportArgs() { Tram = e.Tram, FromStation = e.FromStation, ToStation = e.ToStation, Type = TransportArgsType.Arrival, TriggerTime = e.TriggerTime, }); } else { //enqueue it to the station for arrival when the other trams leave it e.ToStation.TramsQueue.Enqueue(e.Tram); } }
private void EmbarkDisembarkPassengers(TransportArgs e, ref int totalEmbarkingPassengers, ref int totalDisembarkingPassengers) { var min = 0; if (e.ToStation.TimeOfLastTram.HasValue) { min = e.ToStation.TimeOfLastTram.Value; } // handle boarding ? how many people can board? totalDisembarkingPassengers = e.Tram.GetDisembarkingPassengers(e.ToStation, e.TriggerTime); // people exit train e.Tram.CurrentPassengers -= totalDisembarkingPassengers; // get the number of people that have been here before var leftOverPeople = e.ToStation.LeftBehind; // increment the waiting time of these people it will be the number of the people * the time the platform has been empty. e.ToStation.IncrementLeftBehindAverageWaiting(e.TriggerTime - min); // get the number of new passengers that arrived at the platform while it had no tram. var toEmbark = e.ToStation.GetEmbarkingPassengers(e.Tram, e.TriggerTime); // This many people can enter var canEnter = Math.Max(0, 420 - e.Tram.CurrentPassengers); // First we have to board the left behind people because they put the waiting times through the roof. if (leftOverPeople <= canEnter) { e.Tram.CurrentPassengers += leftOverPeople; totalEmbarkingPassengers += leftOverPeople; e.ToStation.LeftBehind -= Math.Max(0, leftOverPeople); } else { // Some get in, but some people will be left behind (again). e.Tram.CurrentPassengers += canEnter; totalEmbarkingPassengers += canEnter; // Now, count the people that are left behind. e.ToStation.LeftBehind = leftOverPeople - canEnter; } //update people that can enter canEnter = Math.Max(0, 420 - e.Tram.CurrentPassengers); // Easy case, the people that have been waiting, can board. All of them if (toEmbark <= canEnter) { e.Tram.CurrentPassengers += toEmbark; totalEmbarkingPassengers += toEmbark; } else { // Some get in, but some people will be left behind. e.Tram.CurrentPassengers += canEnter; totalEmbarkingPassengers += canEnter; // Now, the toEmbark, become LeftBehind. var leftBehind = toEmbark - canEnter; e.ToStation.LeftBehind += leftBehind; } }
private void HandleArrival(object sender, TransportArgs e) { // if the station is terminal, the train will arrive to the main platform //muy importante not to forget this e.ToStation.CurrentTram = e.Tram; //train has arrived at station and is ready to serve passengers var totalEmbarkingPassengers = 0; var totalDisembarkingPassengers = 0; //Disembark passengers if neccessary EmbarkDisembarkPassengers(e, ref totalEmbarkingPassengers, ref totalDisembarkingPassengers); e.ToStation.TotalPassengersServiced += totalEmbarkingPassengers; //compute how long we have to wait var stationDwell = GetStationTime(totalEmbarkingPassengers, totalDisembarkingPassengers); var departTime = e.TriggerTime + stationDwell; //we need to make a turnaround now, this takes Turnaround time if (e.ToStation.IsTerminal) { var turnaroundTime = TurnaroundTime; if (e.FromStation == Track.GetPRDepot()) { turnaroundTime = 0; } // people board while waiting var currentTime = e.TriggerTime + Math.Max(turnaroundTime, stationDwell); var tramDepartureFromTerminal = e.Tram.DepartureFromPreviousTerminal; if (tramDepartureFromTerminal != int.MinValue) { //Get next departure time var nextDepartureTime = e.ToStation.Timetable.GetNextDepartureTime(tramDepartureFromTerminal); //we're done if (nextDepartureTime == null) { return; } //how long more did we take than expected? (higher is WORSE) var punctuality = currentTime - nextDepartureTime.Value; //Check if this tram was very late :/ if (punctuality > LatenessThreshold) { e.Tram.WasLate = true; if (punctuality > MaxDepartureLateness) { MaxDepartureLateness = punctuality; } } //arriving early is good :)))) TotalPunctuality += Math.Max(punctuality, 0); } } // upon arrival schedule a departure EventQueue.Add(new TransportArgs { FromStation = e.ToStation, ToStation = Track.NextStation(e.ToStation), TriggerTime = departTime, Tram = e.Tram, Type = TransportArgsType.ExpectedDeparture }); }