/// <summary> /// Calculates the shortest path between the airplane and the point through which it has to leave the airspace. /// </summary> /// <param name="points">All the checkpoints in the airspace. No airstrips, no airplanes.</param> /// <param name="exitCheckpoint">The checkpoint through which the plane has to leave the airspace.</param> public void CalculateShortestPathLeavingAirspace(List <Checkpoint> points) { this.ReachableNodes.Clear(); this.ShortestPath.Clear(); foreach (Checkpoint point in points) { if (target == null && point.ParentCellType == CellType.FINAL) { this.AddSingleDestination(point, CalculateTimeBetweenPoints(point)); } else if (target != null && target.Equals(ShortestPath.Last) ) //if this doesn't work: ((Checkpoint)target.Value).ParentCellType == Cell.BORDER { ShortestPath.Clear(); ShortestPath.AddFirst(target); return; } else if (target != null && point.ParentCellType == ((Checkpoint)target.Value).ParentCellType) { this.AddSingleDestination(point, CalculateTimeBetweenPoints(point)); } point.ShortestPath.Clear(); point.DistanceFromSource = int.MaxValue; } exitDestination.DistanceFromSource = int.MaxValue; exitDestination.ShortestPath.Clear(); HashSet <AbstractCheckpoint> settledCheckpoints = new HashSet <AbstractCheckpoint>(); HashSet <AbstractCheckpoint> unsettledCheckpoints = new HashSet <AbstractCheckpoint> { this }; while (unsettledCheckpoints.Count != 0) { AbstractCheckpoint currentCheckpnt = this.GetLowestDistanceNode(unsettledCheckpoints); unsettledCheckpoints.Remove(currentCheckpnt); foreach (var pair in currentCheckpnt.ReachableNodes) { AbstractCheckpoint reachableCheckpoint = pair.Key; double edgeWeight = pair.Value; if (!settledCheckpoints.Contains(reachableCheckpoint)) { var shortestPath = CalculateMinDistance(reachableCheckpoint, edgeWeight, currentCheckpnt); if (shortestPath != null && reachableCheckpoint.GetType() == typeof(Checkpoint) && ((Checkpoint)reachableCheckpoint).ParentCellType == CellType.BORDER) { shortestPath.AddLast(reachableCheckpoint); this.ShortestPath = new LinkedList <AbstractCheckpoint>(); var pathNode = shortestPath.First; while (pathNode != null) { this.ShortestPath.AddLast(pathNode.Value); pathNode = pathNode.Next; } } unsettledCheckpoints.Add(reachableCheckpoint); } } settledCheckpoints.Add(currentCheckpnt); } if (this.ShortestPath.Count != 0) { movingDirectionHasChanged = true; target = ShortestPath.First; target = target.Next; } }
/// <summary> /// Calculates the shortest path between the airplane and its final destination - the airstrip. /// </summary> /// <param name="points">All the checkpoints in the airspace. No airstrips, no airplanes.</param> /// <param name="landingStrip">The landing strip the airplane is going for.</param> public void CalculateShortestPathToAirstrip(List <Checkpoint> points, Airstrip landingStrip) { this.ReachableNodes.Clear(); this.ShortestPath.Clear(); foreach (Checkpoint point in points) { if (target == null && (point.ParentCellType == CellType.UPPER || point.ParentCellType == CellType.UNASSIGNED)) { this.AddSingleDestination(point, CalculateTimeBetweenPoints(point)); } else if (target != null && target.Value.GetType() == typeof(Airstrip)) { ShortestPath.Clear(); ShortestPath.AddFirst(target); return; } else if (target != null && point.ParentCellType == ((Checkpoint)target.Value).ParentCellType) { this.AddSingleDestination(point, CalculateTimeBetweenPoints(point)); } point.ShortestPath.Clear(); point.DistanceFromSource = int.MaxValue; } landingStrip.DistanceFromSource = int.MaxValue; landingStrip.ShortestPath.Clear(); HashSet <AbstractCheckpoint> settledCheckpoints = new HashSet <AbstractCheckpoint>(); HashSet <AbstractCheckpoint> unsettledCheckpoints = new HashSet <AbstractCheckpoint> { this }; while (unsettledCheckpoints.Count != 0) { AbstractCheckpoint currentCheckpnt = this.GetLowestDistanceNode(unsettledCheckpoints); unsettledCheckpoints.Remove(currentCheckpnt); foreach (var pair in currentCheckpnt.ReachableNodes) { AbstractCheckpoint reachableCheckpoint = pair.Key; double edgeWeight = pair.Value; if (!settledCheckpoints.Contains(reachableCheckpoint)) { var shortestPath = CalculateMinDistance(reachableCheckpoint, edgeWeight, currentCheckpnt); if (shortestPath != null && reachableCheckpoint.GetType() == typeof(Airstrip)) { shortestPath.AddLast(reachableCheckpoint); this.ShortestPath = new LinkedList <AbstractCheckpoint>(); var pathNode = shortestPath.First; while (pathNode != null) { this.ShortestPath.AddLast(pathNode.Value); pathNode = pathNode.Next; } } unsettledCheckpoints.Add(reachableCheckpoint); } } settledCheckpoints.Add(currentCheckpnt); } if (this.ShortestPath.Count != 0) { movingDirectionHasChanged = true; target = ShortestPath.First; target = target.Next; } }