public bool PathFound(HexKeyValuePair <int, DirectedPath> item) { var path = item.Value; var hex = path.PathStep.Hex; if (_closed.Contains(hex.Coords)) { return(false); } _open.Add(item.Value.PathStep.Hex.Coords, item.Value); TraceFlags.FindPathDequeue.Trace( "Dequeue Path at {0} w/ cost={1,4} at {2}; estimate={3,4}:{4,4}.", item.Value.PathStep.Hex.Coords, item.Value.TotalCost, item.Value.HexsideExit, item.Key >> 16, item.Key & 0xFFFF); if (hex.Coords.Equals(_start.Coords)) { Path = path; return(true); } _closed.Add(hex.Coords); FastHexsideList.ForEach((Action <Hexside>)(hexside => Invoke(path, hexside))); return(false); }
public PathQueueFunctor(IHex start, IHex goal, Func <int, int> heuristic, Func <IHex, Hexside, int> stepCost, IPriorityQueue <int, DirectedPath> queue ) { _vectorGoal = goal.Coords.Canon - start.Coords.Canon; TraceFlags.FindPathDetail.Trace(true, "Find path from {0} to {1}; vectorGoal = {2}", start.Coords, goal.Coords, _vectorGoal); Path = null; _start = start; _heuristic = heuristic; _open = (IDictionary <HexCoords, IDirectedPath>) new Dictionary <HexCoords, IDirectedPath>(); _stepCost = stepCost; _queue = queue; }
public void Invoke(DirectedPath path, Hexside hexside) { var here = path.PathStep.Hex; var there = here.Board[here.Coords.GetNeighbour(hexside)]; if (there != null && !_open.ContainsKey(there.Coords)) { var cost = _stepCost(there, hexside.Reversed()); if (cost > 0) { var newPath = path.AddStep(there, hexside, cost); var estimate = Estimate(_heuristic, _vectorGoal, _start.Coords, newPath.PathStep.Hex.Coords, newPath.TotalCost); TraceFlags.FindPathEnqueue.Trace(" Enqueue {0}: estimate={1,4}:{2,3}", there.Coords, estimate >> 16, estimate & 0xFFFF); _queue.Enqueue(estimate, newPath); } } }
BidirectionalPathfinder(IHex start, IHex goal, LandmarkCollection landmarks, HashSet<HexCoords> closed, Func<double> 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); }
public void SetBestSoFar(DirectedPath pathFwd, DirectedPath pathRev) { if (pathFwd == null || pathRev == null) return; if (pathFwd.TotalCost + pathRev.TotalCost < BestSoFar) { _pathFwd = pathFwd; _pathRev = pathRev; BestSoFar = _pathFwd.TotalCost + pathRev.TotalCost; KeySoFar = _pathFwd.Key + _pathRev.Key; } }
public static DirectedPath MergePaths(DirectedPath fwd, DirectedPath rev) { if (rev != null) { while (rev.PathSoFar != null) { var hexside = rev.PathStep.HexsideEntry; var cost = rev.TotalCost - (rev = rev.PathSoFar).TotalCost; fwd = fwd.AddStep(rev.PathStep.Hex, hexside, cost, (int)cost); } } return fwd; }
void ExpandHex(DirectedPath path, Hexside hexside) { var here = path.PathStep.Hex; var there = here.Neighbour(hexside); if (there != null && !_closed.Contains(there.Coords)) { var cost = _stepCost(here, hexside, there); if ((cost > 0) ) { if ((path.TotalCost + cost < _getBestSoFar() || !_open.ContainsKey(there.Coords)) ) { var totalCost = cost + path.TotalCost; var key = Estimate(here, there, totalCost); var newPath = _addStep(path, there, hexside, cost); DirectedPath oldPath; if (!_open.TryGetValue(there.Coords, out oldPath)) { _open.Add(there.Coords, newPath); _queue.Enqueue(key, newPath); } else if (newPath.TotalCost < oldPath.TotalCost) { _open.Remove(there.Coords); _open.Add(there.Coords, newPath); _queue.Enqueue(key, newPath); } _setBestSoFar(newPath, Partner.GetPartnerPath(there.Coords)); } } } }