/// <summary>Creates a populated <see cref="Collection{T}"/> of <see cref="Landmark"/> /// instances.</summary> /// <param name="board">The board on which the collection of landmarks is to be instantiated.</param> /// <param name="landmarkCoords">Board coordinates of the desired landmarks</param> public static ILandmarkCollection CreateLandmarks( IHexBoard <IHex> board, IFastList <HexCoords> landmarkCoords ) { if (landmarkCoords == null) { throw new ArgumentNullException("landmarkCoords"); } ILandmarkCollection tempLandmarks = null, landmarks = null; try { tempLandmarks = new LandmarkCollection(( from coords in landmarkCoords.AsParallel().AsOrdered() where board.IsOnboard(coords) select new Landmark(coords, board) ).ToList <ILandmark>()); landmarks = tempLandmarks; tempLandmarks = null; } finally { if (tempLandmarks != null) { tempLandmarks.Dispose(); } } return(landmarks); }
public static LandmarkCollection CreateLandmarks( IBoard <IHex> board, IList <HexCoords> landmarkCoords ) { if (landmarkCoords == null) { throw new ArgumentNullException("landmarkCoords"); } var list = new List <Landmark>(landmarkCoords.Count); for (var i = 0; i < landmarkCoords.Count; i++) { list.Add(new Landmark(landmarkCoords[i], null)); } var landmarks = new LandmarkCollection(list); if (board != null) { landmarks.ResetLandmarks(board); } return(landmarks); }
/// <summary>(Re)calculates distances for all landmarks using the provided IBoard<IHex> definition.</summary> /// <param name="this">The </param> /// <param name="board">The </param> public static void ResetLandmarks(this LandmarkCollection @this, IBoard <IHex> board) { if (board == null) { throw new ArgumentNullException("board"); } Parallel.For(0, @this.Count, i => @this[i].FillLandmark(board)); }
/// <summary>Create a new instance of <see cref="PathfinderRev"/>.</summary> /// <param name="start"></param> /// <param name="goal"></param> /// <param name="stepCost"></param> /// <param name="landmarks"></param> /// <param name="closed"></param> /// <param name="setBestSoFar"></param> /// <param name="getBestSoFar"></param> public PathfinderRev(IHex start, IHex goal, Func <IHex, Hexside, int> stepCost, LandmarkCollection landmarks, HashSet <HexCoords> closed, Action <DirectedPath, DirectedPath> setBestSoFar, Func <int> getBestSoFar ) : base(goal, start, landmarks, closed, getBestSoFar) { _addStep = (path, there, hexside, cost) => path.AddStep(there, hexside.Reversed(), cost); _setBestSoFar = (self, partner) => setBestSoFar(partner, self); _stepCost = (here, hexside, there) => stepCost(here, hexside); _search = "Rev"; TraceFlags.FindPathDetail.Trace(" {0} Search uses: vectorGoal = {1}; and landmark at {2}", _search, _vectorGoal, _landmark.Coords); }
/// <summary>Returns an <c>IPath</c> for the optimal path from coordinates <c>start</c> to <c>goal</c>.</summary> /// <param name="start">Coordinates for the <c>last</c> step on the desired path.</param> /// <param name="goal">Coordinates for the <c>first</c> step on the desired path.</param> /// <param name="stepCost">Cost to extend path by hex at <c>coords</c> from hex at direction <c>hexside</c>.</param> /// <param name="landmarks"><c>LandmarkCollection</c> of landmarks available for heuristic calculation.</param> static PathHalves FindDirectedPath( IHex start, IHex goal, Func <IHex, Hexside, int> stepCost, LandmarkCollection landmarks ) { if (start == null) { throw new ArgumentNullException("start"); } if (goal == null) { throw new ArgumentNullException("goal"); } if (stepCost == null) { throw new ArgumentNullException("stepCost"); } if (landmarks == null) { throw new ArgumentNullException("landmarks"); } TraceFlags.FindPathDetail.Trace(true, "Fwd: Find path from {0} to {1}:", start.Coords, goal.Coords); var closed = new HashSet <HexCoords>(); var pathHalves = new PathHalves(); var pathfinderFwd = new PathfinderFwd(start, goal, stepCost, landmarks, closed, pathHalves.SetBestSoFar, () => pathHalves.BestSoFar); var pathfinderRev = new PathfinderRev(start, goal, stepCost, landmarks, closed, pathHalves.SetBestSoFar, () => pathHalves.BestSoFar); pathfinderFwd.Partner = pathfinderRev; var pathfinder = pathfinderRev.Partner = pathfinderFwd; while (!pathfinder.IsFinished()) { pathfinder = pathfinder.Partner; } return(pathHalves); }
BidirectionalPathfinder(IHex start, IHex goal, LandmarkCollection landmarks, HashSet <HexCoords> closed, Func <int> getBestSoFar ) { _start = start; _goal = goal; _getBestSoFar = getBestSoFar; _vectorGoal = goal.Coords.Canon - start.Coords.Canon; _open = new Dictionary <HexCoords, DirectedPath>(); _closed = closed; _queue = new HotPriorityQueue <DirectedPath>(16); _landmark = landmarks .OrderByDescending(l => l.HexDistance(goal.Coords) - l.HexDistance(start.Coords)) .FirstOrDefault(); _heuristic = c => _landmark.HexDistance(c) - _landmark.HexDistance(start.Coords); var path = new DirectedPath(goal); _open.Add(goal.Coords, path); _queue.Enqueue(0, path); }