Пример #1
0
        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
            });
        }
Пример #2
0
        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
            });
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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;
            }
        }
Пример #5
0
        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
            });
        }