/* Parallel */ /// <summary> /// Returns if dst can be reached from src /// </summary> public static bool CanReach(IAStarEnvironment environment, IntPoint3 src, IntPoint3 dst, DirectionSet dstPositioning) { Debug.Assert(environment != null); // Do pathfinding to both directions simultaneously to detect faster if the destination is blocked CancellationTokenSource cts = new CancellationTokenSource(); AStarResult resBackward = null; AStarResult resForward = null; var taskForward = new Task(delegate { resForward = Find(environment, src, DirectionSet.Exact, dst, dstPositioning, 200000, cts.Token); }); taskForward.Start(); var taskBackward = new Task(delegate { resBackward = Find(environment, dst, dstPositioning, src, DirectionSet.Exact, 200000, cts.Token); }); taskBackward.Start(); Task.WaitAny(taskBackward, taskForward); cts.Cancel(); Task.WaitAll(taskBackward, taskForward); if (resForward.Status == AStarStatus.Found || resBackward.Status == AStarStatus.Found) return true; else return false; }
/// <summary> /// Find route from src to dest, finding the route in parallel from both directions /// </summary> public static IEnumerable<Direction> Find(IAStarEnvironment environment, IntPoint3 src, IntPoint3 dest, DirectionSet positioning) { AStarResult resBackward; AStarResult resForward; ParallelFind(environment, src, dest, positioning, out resBackward, out resForward); IEnumerable<Direction> dirs; if (resForward.Status == AStarStatus.Found) dirs = resForward.GetPath(); else if (resBackward.Status == AStarStatus.Found) dirs = resBackward.GetPathReverse(); else dirs = null; return dirs; }
/// <summary> /// Find route from src to destination defined by IAstarTarget /// </summary> public static AStarResult Find(IAStarEnvironment environment, IntPoint3 src, DirectionSet srcPositioning, IAStarTarget target, int maxNodeCount = 200000, CancellationToken? cancellationToken = null) { var astar = new AStarImpl(environment, src, srcPositioning, target, maxNodeCount, cancellationToken); var status = astar.Find(); return new AStarResult(astar.Nodes, astar.LastNode, status); }
/// <summary> /// Find route from src to dst, using the given positionings /// </summary> public static AStarResult Find(IAStarEnvironment environment, IntPoint3 src, DirectionSet srcPositioning, IntPoint3 dst, DirectionSet dstPositioning, int maxNodeCount = 200000, CancellationToken? cancellationToken = null) { return Find(environment, src, srcPositioning, new AStarDefaultTarget(dst, dstPositioning), maxNodeCount, cancellationToken); }
public AStarImpl(IAStarEnvironment environment, IntPoint3 src, DirectionSet srcPositioning, IAStarTarget target, int maxNodeCount = 200000, CancellationToken? cancellationToken = null) { m_environment = environment; m_src = src; m_srcPositioning = srcPositioning; m_maxNodeCount = maxNodeCount; m_cancellationToken = cancellationToken.HasValue ? cancellationToken.Value : CancellationToken.None; m_target = target; m_nodeMap = new Dictionary<IntPoint3, AStarNode>(); m_openList = new BinaryHeap<AStarNode>(); AddInitialNodes(); }
static void ParallelFind(IAStarEnvironment environment, IntPoint3 src, IntPoint3 dest, DirectionSet positioning, out AStarResult resBackward, out AStarResult resForward) { Debug.Assert(environment != null); // Do pathfinding to both directions simultaneously to detect faster if the destination is blocked CancellationTokenSource cts = new CancellationTokenSource(); AStarResult rb = null; AStarResult rf = null; var taskForward = new Task(delegate { rf = Find(environment, src, DirectionSet.Exact, dest, positioning, 200000, cts.Token); }); taskForward.Start(); var taskBackward = new Task(delegate { rb = Find(environment, dest, positioning, src, DirectionSet.Exact, 200000, cts.Token); }); taskBackward.Start(); Task.WaitAny(taskBackward, taskForward); cts.Cancel(); Task.WaitAll(taskBackward, taskForward); resForward = rf; resBackward = rb; }
/// <summary> /// Flood-find the nearest location for which func returns true /// </summary> public static AStarResult FindNearest(IAStarEnvironment environment, IntPoint3 src, Func<IntPoint3, bool> func, int maxNodeCount = 200000) { return Find(environment, src, DirectionSet.Exact, new AStarDelegateTarget(func), maxNodeCount); }
public static IEnumerable<AStarResult> FindMany(IAStarEnvironment environment, IntPoint3 src, DirectionSet srcPositioning, IAStarTarget target, int maxNodeCount = 200000, CancellationToken? cancellationToken = null) { var astar = new AStarImpl(environment, src, srcPositioning, target, maxNodeCount, cancellationToken); AStarStatus status; while ((status = astar.Find()) == AStarStatus.Found) yield return new AStarResult(astar.Nodes, astar.LastNode, status); }
public static IEnumerable<AStarResult> FindMany(IAStarEnvironment environment, IntPoint3 src, DirectionSet srcPositioning, Func<IntPoint3, bool> func, int maxNodeCount = 200000, CancellationToken? cancellationToken = null) { return FindMany(environment, src, srcPositioning, new AStarDelegateTarget(func), maxNodeCount, cancellationToken); }
/// <summary> /// Find route from src to dest, finding the route in parallel from both directions /// </summary> public static IEnumerable<Direction> Find(IAStarEnvironment environment, IntPoint3 src, IntPoint3 dest, DirectionSet positioning, out IntPoint3 finalLocation) { AStarResult resBackward; AStarResult resForward; ParallelFind(environment, src, dest, positioning, out resBackward, out resForward); IEnumerable<Direction> dirs; if (resForward.Status == AStarStatus.Found) { dirs = resForward.GetPath(); finalLocation = resForward.LastNode.Loc; } else if (resBackward.Status == AStarStatus.Found) { dirs = resBackward.GetPathReverse(); AStarNode n = resBackward.LastNode; while (n.Parent != null) n = n.Parent; finalLocation = n.Loc; } else { dirs = null; finalLocation = new IntPoint3(); } return dirs; }