private TimeSpan CalculateTravelTime(TravelPlanData data) { int trainSpeed = Trains.Find(t => t.ID == data.TrainID).MaxSpeed; StationConnection currentConnection = GetStationConnection(data.StartStationID, data.ArriveStationID); int distanceFactor = 10; int distanceInKm = currentConnection.Distance * distanceFactor; int travelDurationInMinutes = (int)Math.Ceiling(Convert.ToDouble(distanceInKm) / trainSpeed * 60); return(new TimeSpan().Add(TimeSpan.FromMinutes(travelDurationInMinutes))); }
public ITravelPlanner ArriveAt(int stationId, string time) { if (Stations.FirstOrDefault(s => s.ID == stationId) is null) { throw new Exception("CanĀ“t find this station, please choose another station"); } TimeSpan parsedTime; try { parsedTime = TimeSpan.Parse(time); } catch { throw new Exception("Invalid time format"); } // I want to find the last spot of the travelPlanDatas list to add to it, we are adding the arrive at data TravelPlanData workingData = travelPlanDatas[^ 1];
public void Simulate() { TimeSpan earliestStartTime = travelPlanDatas.Min(d => d.StartTime); Clock.Time = earliestStartTime.Subtract(TimeSpan.FromMinutes(10)); Console.WriteLine($"Clock set to: {earliestStartTime}."); Clock.IsPrintingTime = true; int maxEventAmount = travelPlanDatas.Count * 2; int eventCounter = 0; List <StationConnection> trackSections = TrackDescription.StationConnections; while (true) { TimeSpan clockTime = Clock.Time; string timeString = clockTime.ToString(@"hh\:mm", CultureInfo.InvariantCulture); for (int i = 0; i < travelPlanDatas.Count; i++) { TravelPlanData data = travelPlanDatas[i]; // ----Level crossing ---- StationConnection connectionWithCrossing = trackSections.FirstOrDefault(s => s.StartStationID == travelPlanDatas[i].StartStationID && s.ArriveStationID == travelPlanDatas[i].ArriveStationID && s.TrackParts.Contains('=')); hasLevelCrossing = connectionWithCrossing != null; if (hasLevelCrossing) { // level crossing is located between two stations levelCrossing = connectionWithCrossing.Distance * 10 / 2.0; maxSpeed = Trains.Find(train => train.ID == data.TrainID).MaxSpeed; currentPosition = 1.0 * (clockTime.Subtract(data.StartTime)).TotalHours * maxSpeed; if (!TrainsNearLevelCrossing.Contains(data.TrainID) && currentPosition >= levelCrossing - border && currentPosition <= levelCrossing + border) { TrainsNearLevelCrossing.Add(data.TrainID); // Add a train to the TrainsNearLevelCrossing list when the train approches level crossing } } // check if data HasStarted if (!data.HasStarted && data.StartTime <= clockTime) { string trainName = Trains.Find(train => train.ID == data.TrainID).Name; string stationName = Stations.Find(station => station.ID == data.StartStationID).StationName; travelPlanDatas[i].HasStarted = true; TimeSpan travelTime = CalculateTravelTime(data); int timeDeviationInMinutes = GetTimeDeviationInMinutes(data.StartTime, data.ArriveTime, travelTime); travelPlanDatas[i].TimeDeviationInMinutes = timeDeviationInMinutes; travelPlanDatas[i].ArriveTime = data.StartTime.Add(travelTime); eventCounter++; string output = $"[{timeString}]: {trainName} is departing from {stationName}."; Console.WriteLine(output); } else if (hasLevelCrossing && currentPosition >= levelCrossing - border && currentPosition <= levelCrossing + border && isOpen) { CloseLevelCrossing(timeString); // close level crossing when the train is near } else if (hasLevelCrossing && currentPosition > levelCrossing + border && TrainsNearLevelCrossing.Contains(data.TrainID)) { TrainsNearLevelCrossing.Remove(data.TrainID); // when the train leaves zone near level crossing remove it from TrainsNearLevelCrossing list if (!isOpen && TrainsNearLevelCrossing.Count() == 0) // open level crossing if there are no other trains near { OpenLevelCrossing(timeString); } } // check if data HasArrived else if (!data.HasArrived && data.ArriveTime <= clockTime) { string trainName = Trains.Find(train => train.ID == data.TrainID).Name; string stationName = Stations.Find(station => station.ID == data.ArriveStationID).StationName; travelPlanDatas[i].HasArrived = true; eventCounter++; string output = $"[{timeString}]: {trainName} is arriving at {stationName}."; if (data.TimeDeviationInMinutes > 0) { output += $" The train was delayed by {data.TimeDeviationInMinutes} minutes."; } else if (data.TimeDeviationInMinutes < 0) { output += $" The train is early by {Math.Abs(data.TimeDeviationInMinutes)} minutes."; } Console.WriteLine(output); } } if (eventCounter == maxEventAmount) { break; } Thread.Sleep(10); } }