/// <summary> /// Uses DFS to trace the next non-looped path between the path length constraint /// </summary> /// <returns>The non looped path.</returns> /// <param name="startingWaypoint">Starting waypoint.</param> Waypoint[] FindNonLoopedPath(Waypoint startingWaypoint) { var stack = new Stack<List<Waypoint>>(); var startPath = new List<Waypoint>(); startPath.Add(startingWaypoint); stack.Push(startPath); while (stack.Count > 0) { var topPath = stack.Pop(); var lastPoint = topPath[topPath.Count - 1]; var children = lastPoint.AdjacentWaypoints; // Suffle the child nodes before iterating for randomness children = Shuffle (children); var nextPathLength = topPath.Count + 1; // Add one to account for the next node that would be added foreach (var child in children) { var visited = topPath.Contains(child); if (visited) continue; var nextPath = new List<Waypoint>(); nextPath.AddRange(topPath); nextPath.Add(child); // TODO: Add more randomness here to that the length varies between the min/max path length range if (nextPathLength >= minPathLength) { // Found our path with the desired length return nextPath.ToArray(); } stack.Push(nextPath); } } return null; }
Waypoint[] Shuffle(Waypoint[] data) { // TODO: Implement return data; }
Waypoint FindNearest(Waypoint[] waypoints, Vector3 startingPoint) { float nearestDistance = float.MaxValue; Waypoint bestMatch = null; foreach (var waypoint in waypoints) { var distanceSq = (waypoint.gameObject.transform.position - startingPoint).sqrMagnitude; if (nearestDistance > distanceSq) { bestMatch = waypoint; nearestDistance = distanceSq; } } return bestMatch; }
/// <summary> /// Uses BFS to trace a path back to the starting node, with the length between min/max constraint /// </summary> /// <returns>The looped path.</returns> /// <param name="startingWaypoint">Starting waypoint.</param> Waypoint[] FindLoopedPath(Waypoint startingWaypoint) { if (startingWaypoint == null || startingWaypoint.AdjacentWaypoints.Length <= 0) { // A loop cannot be made when the starting node has only one outgoing path return null; } // Use BFS to find the nearest path; var queue = new Queue<List<Waypoint>>(); var startPath = new List<Waypoint>(); startPath.Add (startingWaypoint); queue.Enqueue(startPath); while (queue.Count > 0) { var topPath = queue.Dequeue(); var nextPathLength = topPath.Count + 1; // Add one to account for the next node that would be added if (nextPathLength > maxPathLength) { // Path will be too big if more nodes are added. bail out from this branch continue; } // Suffle the child nodes before iterating for randomness var validPathLength = (topPath.Count >= minPathLength && topPath.Count <= maxPathLength); var lastPoint = topPath[topPath.Count - 1]; var children = lastPoint.AdjacentWaypoints; children = Shuffle(children); foreach (var child in children) { var visited = topPath.Contains(child); if (!visited) { var nextPath = new List<Waypoint>(); nextPath.AddRange(topPath); nextPath.Add (child); queue.Enqueue(nextPath); } else if (validPathLength && child == startingWaypoint) { // The path length matches the constraint and the next child connects back to the starting point return topPath.ToArray(); } } } // No loops found return null; }