void Update() { if (results.Count > 0) { int itemsInQueue = results.Count; lock (results) { for (int i = 0; i < itemsInQueue; i++) { PathResult result = results.Dequeue(); result.callback(result.path, result.success); } } } }
private IEnumerator <float> Tick() { while (true) { nResultCount = queue_PathResults.Count; if (nResultCount > 0) { lock (queue_PathResults) { for (int i = 0; i < nResultCount; i++) { PathResult mPathResult = queue_PathResults.Dequeue(); mPathResult.OnPathProcessed(mPathResult.RequestID, mPathResult.Path, mPathResult.Success); } } } yield return(Timing.WaitForSeconds(1f)); } }
private IEnumerator ReadPathfindingResults() { while (true) { yield return(_wfs); lock (results) { //read only in case that we have a result queued up. if (results.Count > 0) { PathResult result = results.Dequeue(); if (PathfindingAlgorithms.isDebugMode) { //AStar.DebugPath(result.path); result.callback(result.path, result.success); } } } } }
public PathResult pathFromTo(Region region, Tile start, Tile goal, bool playersCanBlockPath = false) { PathResult pathResult = new PathResult(); PathTile goalPt = new PathTile(goal); // set up lists PriorityQueue <PathTile> frontier = new PriorityQueue <PathTile>(); Dictionary <Vector2Int, PathTile> explored = new Dictionary <Vector2Int, PathTile>(); Dictionary <Vector2Int, PathTile> previous = new Dictionary <Vector2Int, PathTile>(); Dictionary <Vector2Int, float> costs = new Dictionary <Vector2Int, float>(); PathTile crt; crt = new PathTile(start); crt.depth = 0; frontier.Enqueue(crt, 0); previous[crt.tile.index] = null; costs[crt.tile.index] = 0; // start pathfinding while (!frontier.IsEmpty()) { // get current crt = frontier.Dequeue(); // record that the tile was explored explored[crt.tile.index] = crt; if (crt.equals(goalPt)) { // reached goal; search complete pathResult.reachedGoal = true; pathResult.pathCost = costs[crt.tile.index]; break; } // get neighbor tiles List <PathTile> neighbors = new List <PathTile>(); foreach (Tile neighborTile in region.getTileNeighbors(crt.tile.index)) { PathTile neighbor = new PathTile(neighborTile); //neighborPt.cost = crt.cost + costBetween(crt, neighborPt); neighbor.depth = crt.depth + 1; neighbors.Add(neighbor); } // add neighbor tiles to search float cost, priority; foreach (PathTile neighbor in neighbors) { // check if exceeding max depth if (neighbor.depth > maxDepth) { break; } // compute cost float _cost = costBetween(crt, neighbor); //// check if path is blocked by another player //if (playersCanBlockPath && GameControl.gameSession.checkForPlayersAt(neighbor.tile) != null) //{ // if (!neighbor.CompareTo(goalPt)) // ensures that you can move to a tile with an enemy // _cost = float.PositiveInfinity; // set highest cost to signify that the tile is unreachable //} cost = costs[crt.tile.index] + _cost; if (cost <= maxCost) { if (!costs.ContainsKey(neighbor.tile.index) || cost < costs[neighbor.tile.index]) { costs[neighbor.tile.index] = cost; // compute heuristic priority priority = cost + heuristic(region, neighbor, goalPt); priority -= neighbor.depth * heuristicDepthInfluence; // makes so that tiles closest to goal are more eagerly explored frontier.Enqueue(neighbor, priority); previous[neighbor.tile.index] = crt; } } } } // build list of tiles on path if goal was reached if (pathResult.reachedGoal) { pathResult.addPathtile(goalPt); crt = previous[goal.index]; while (crt != null) { pathResult.addPathtile(crt); crt = previous[crt.tile.index]; } } foreach (PathTile pt in explored.Values) { pathResult.addExploredPathtile(pt); } return(pathResult); }
public PathResult pathFromTo(Region region, Tile start, Tile goal, bool playersCanBlockPath = false) { // attempt normal Dijsktra pathfinder first PathResult pr = DijsktraPF.pathFromTo( region, start, goal, playersCanBlockPath ); if (pr.reachedGoal) { return(pr); } // get full path to tile even if its out of range PathResult prA = AstarPF.pathFromTo( region, start, goal, playersCanBlockPath ); // get move range PathResult prD = DijsktraPF.pathFromTo( region, start, new Tile(new Vector3(float.MaxValue, float.MaxValue, float.MaxValue), int.MaxValue, int.MaxValue), playersCanBlockPath ); // get the last tile given by astar pathfinder to goal that is still within move range Tile _goal = null; if (prA.reachedGoal) { foreach (Tile t in prA.getTilesOnPathStartFirst()) { bool outOfRange = true; foreach (Tile explored in prD.getExploredTiles()) { if (t.pos == explored.pos) { _goal = t; outOfRange = false; break; } } if (outOfRange) { break; } } } if (_goal != null) { return(DijsktraPF.pathFromTo( region, start, _goal, playersCanBlockPath )); } else { return(prD); } }