/** @param pathFinder the path finder * @param timeToRun the time in nanoseconds that this call can use on the current frame * @return {@code true} if the search has completed; {@code false} if more time is needed to complete. */ public boolean search (PathFinder<N> pathFinder, long timeToRun) { return pathFinder.search(this, timeToRun); }
protected void generateNodePath (N startNode, GraphPath<N> outPath) { // Work back along the path, accumulating nodes // outPath.clear(); while (current.connection != null) { outPath.add(current.node); current = nodeRecords[graph.getIndex(current.connection.getFromNode())]; } outPath.add(startNode); // Reverse the path outPath.reverse(); }
int currentLevel = graph.getLevelCount() - 1; while (currentLevel >= 0) { currentStartNode = graph.convertNodeBetweenLevels(0, startNode, currentLevel); currentEndNode = graph.convertNodeBetweenLevels(levelOfNodes, currentEndNode, currentLevel); if (currentLevel == 0) { N currentEndNodeParent = graph.convertNodeBetweenLevels(0, currentEndNode, 1); if (currentEndNodeParent == graph.convertNodeBetweenLevels(0, endNode, 1) && currentEndNodeParent == graph.convertNodeBetweenLevels(0, startNode, 1)) { currentEndNode = endNode; graph.setLevel(levelOfNodes); outPath.clear(); boolean pathFound = levelPathFinder.searchConnectionPath(currentStartNode, currentEndNode, heuristic, outPath); currentEndNode = outPath.get(0).getToNode();
final MyGraph graph = createGraphFromTextRepresentation(graphDrawing); final IndexedAStarPathFinder<MyNode> pathfinder = new IndexedAStarPathFinder<>(graph); final GraphPath<MyNode> outPath = new DefaultGraphPath<>(); final boolean searchResult = pathfinder.searchNodePath(graph.nodes.get(0), graph.nodes.get(212), new ManhattanDistance(), outPath); Assert.assertEquals("Unexpected number of nodes in path", 32, outPath.getCount());
protected void visitChildren (N endNode, Heuristic<N> heuristic) { Array<Connection<N>> connections = graph.getConnections(current.node); N node = connection.getToNode(); float nodeCost = current.costSoFar + connection.getCost(); NodeRecord<N> nodeRecord = getNodeRecord(node); if (nodeRecord.category == CLOSED) { // The node is closed nodeHeuristic = nodeRecord.getEstimatedTotalCost() - nodeRecord.costSoFar; } else if (nodeRecord.category == OPEN) { // The node is open nodeHeuristic = nodeRecord.getEstimatedTotalCost() - nodeRecord.costSoFar; } else { // the node is unvisited nodeHeuristic = heuristic.estimate(node, endNode); addToOpenList(nodeRecord, nodeCost + nodeHeuristic);
int currentLevel = graph.getLevelCount() - 1; while (currentLevel >= 0) { currentStartNode = graph.convertNodeBetweenLevels(0, startNode, currentLevel); currentEndNode = graph.convertNodeBetweenLevels(levelOfNodes, currentEndNode, currentLevel); if (currentLevel == 0) { N currentEndNodeParent = graph.convertNodeBetweenLevels(0, currentEndNode, 1); if (currentEndNodeParent == graph.convertNodeBetweenLevels(0, endNode, 1) && currentEndNodeParent == graph.convertNodeBetweenLevels(0, startNode, 1)) { currentEndNode = endNode; graph.setLevel(levelOfNodes); outPath.clear(); boolean pathFound = levelPathFinder.searchNodePath(currentStartNode, currentEndNode, heuristic, outPath); currentEndNode = outPath.get(1);
int inputPathLength = path.getCount(); V vec = path.getNodePosition(0); this.ray = new Ray<V>(vec.cpy(), vec.cpy()); ray.start.set(path.getNodePosition(outputIndex - 1)); ray.end.set(path.getNodePosition(inputIndex)); path.swapNodes(outputIndex, inputIndex - 1); outputIndex++; path.swapNodes(outputIndex, inputIndex - 1); path.truncatePath(outputIndex + 1);
protected void initSearch (N startNode, N endNode, Heuristic<N> heuristic) { if (metrics != null) metrics.reset(); // Increment the search id if (++searchId < 0) searchId = 1; // Initialize the open list openList.clear(); // Initialize the record for the start node and add it to the open list NodeRecord<N> startRecord = getNodeRecord(startNode); startRecord.node = startNode; startRecord.connection = null; startRecord.costSoFar = 0; addToOpenList(startRecord, heuristic.estimate(startNode, endNode)); current = null; }
if (timeToRun <= timeTolerance) return false; if (DEBUG) GdxAI.getLogger().debug(TAG, "search begin"); if (!request.initializeSearch(timeToRun)) return false; request.changeStatus(PathFinderRequest.SEARCH_INITIALIZED); lastTime = currentTime; if (timeToRun <= timeTolerance) return false; if (DEBUG) GdxAI.getLogger().debug(TAG, "search path"); if (!request.search(pathFinder, timeToRun)) return false; request.changeStatus(PathFinderRequest.SEARCH_DONE); lastTime = currentTime; if (timeToRun <= timeTolerance) return false; if (DEBUG) GdxAI.getLogger().debug(TAG, "search end"); if (!request.finalizeSearch(timeToRun)) return false; request.changeStatus(PathFinderRequest.SEARCH_FINALIZED);
levelRequest = new LevelPathFinderRequest<N>(); levelRequestControl = new PathFinderRequestControl<N>(); levelRequest.endNode = request.endNode; levelRequest.levelOfNodes = 0; levelRequest.currentLevel = graph.getLevelCount() - 1; boolean finished = levelRequestControl.execute(levelRequest);
startNode = hpf.graph.convertNodeBetweenLevels(0, hpfRequest.startNode, currentLevel); endNode = hpf.graph.convertNodeBetweenLevels(levelOfNodes, endNode, currentLevel); if (currentLevel == 0) { N currentEndNodeParent = hpf.graph.convertNodeBetweenLevels(0, endNode, 1); if (currentEndNodeParent == hpf.graph.convertNodeBetweenLevels(0, hpfRequest.endNode, 1) && currentEndNodeParent == hpf.graph.convertNodeBetweenLevels(0, hpfRequest.startNode, 1)) { endNode = hpfRequest.endNode; hpf.graph.setLevel(levelOfNodes); resultPath.clear(); return true;
private static MyGraph createGraphFromTextRepresentation (final String graphTextRepresentation) { final String[][] tiles = createStringTilesFromGraphTextRepresentation(graphTextRepresentation); for (int y = 0; y < numRows; y++) { for (int x = 0; x < numCols; x++, index++) { nodes[x][y] = new MyNode(index, x, y, 4); indexedNodes.add(nodes[x][y]); nodes[x][y].getConnections().add(new DefaultConnection<MyNode>(nodes[x][y], nodes[x - 1][y])); nodes[x][y].getConnections().add(new DefaultConnection<MyNode>(nodes[x][y], nodes[x + 1][y])); nodes[x][y].getConnections().add(new DefaultConnection<MyNode>(nodes[x][y], nodes[x][y - 1])); nodes[x][y].getConnections().add(new DefaultConnection<MyNode>(nodes[x][y], nodes[x][y + 1])); return new MyGraph(indexedNodes);
public PathFinderQueue (PathFinder<N> pathFinder) { this.pathFinder = pathFinder; this.requestQueue = new CircularBuffer<PathFinderRequest<N>>(16); this.currentRequest = null; this.requestControl = new PathFinderRequestControl<N>(); }
@Override public boolean finalizeSearch (long timeToRun) { hpfRequest.pathFound = pathFound; if (pathFound) { // Take the first move of this plan and use it for the next run through endNode = resultPath.get(1); } if (DEBUG) GdxAI.getLogger().debug(TAG, "LevelPathFinder finalizeSearch; status: " + status); return true; }
@Override public boolean search (PathFinder<N> pathFinder, long timeToRun) { if (DEBUG) GdxAI.getLogger().debug(TAG, "LevelPathFinder search; status: " + status); return super.search(pathFinder, timeToRun); }
@Override public void run (long timeToRun) { // Keep track of the current time requestControl.lastTime = TimeUtils.nanoTime(); requestControl.timeToRun = timeToRun; requestControl.timeTolerance = TIME_TOLERANCE; requestControl.pathFinder = pathFinder; requestControl.server = this; // If no search in progress, take the next from the queue if (currentRequest == null) currentRequest = requestQueue.read(); while (currentRequest != null) { boolean finished = requestControl.execute(currentRequest); if (!finished) return; // Read next request from the queue currentRequest = requestQueue.read(); } }
@Test public void searchNodePath_WhenDestinationUnreachable_ExpectedNoOuputPathFound () { // @off - disable libgdx formatter final String graphDrawing = ".....#....\n" + ".....#....\n" + ".....#...."; // @on - enable libgdx formatter final MyGraph graph = createGraphFromTextRepresentation(graphDrawing); final IndexedAStarPathFinder<MyNode> pathfinder = new IndexedAStarPathFinder<>(graph); final GraphPath<MyNode> outPath = new DefaultGraphPath<>(); // @off - disable libgdx formatter // 0123456789 // S....#...E 0 // .....#.... 10 // .....#.... 20 // @on - enable libgdx formatter final boolean searchResult = pathfinder.searchNodePath(graph.nodes.get(0), graph.nodes.get(9), new ManhattanDistance(), outPath); Assert.assertFalse("Unexpected search result", searchResult); }
protected void generateConnectionPath (N startNode, GraphPath<Connection<N>> outPath) { // Work back along the path, accumulating connections // outPath.clear(); while (current.node != startNode) { outPath.add(current.connection); current = nodeRecords[graph.getIndex(current.connection.getFromNode())]; } // Reverse the path outPath.reverse(); }
int inputPathLength = path.getCount(); V vec = request.path.getNodePosition(0); this.ray = new Ray<V>(vec.cpy(), vec.cpy()); ray.start.set(path.getNodePosition(request.outputIndex - 1)); ray.end.set(path.getNodePosition(request.inputIndex)); path.swapNodes(request.outputIndex, request.inputIndex - 1); request.outputIndex++; path.swapNodes(request.outputIndex, request.inputIndex - 1); path.truncatePath(request.outputIndex + 1);
final MyGraph graph = createGraphFromTextRepresentation(graphDrawing); final IndexedAStarPathFinder<MyNode> pathfinder = new IndexedAStarPathFinder<>(graph); final GraphPath<MyNode> outPath = new DefaultGraphPath<>(); final boolean searchResult1 = pathfinder.searchNodePath(graph.nodes.get(15), graph.nodes.get(25), new ManhattanDistance(), outPath); Assert.assertEquals("Unexpected number of nodes in path", 2, outPath.getCount()); outPath.clear(); final boolean searchResult2 = pathfinder.searchNodePath(graph.nodes.get(15), graph.nodes.get(16), new ManhattanDistance(), outPath); Assert.assertEquals("Unexpected number of nodes in path", 2, outPath.getCount()); outPath.clear(); final boolean searchResult3 = pathfinder.searchNodePath(graph.nodes.get(15), graph.nodes.get(14), new ManhattanDistance(), outPath); Assert.assertEquals("Unexpected number of nodes in path", 2, outPath.getCount()); outPath.clear(); final boolean searchResult4 = pathfinder.searchNodePath(graph.nodes.get(15), graph.nodes.get(5), new ManhattanDistance(), outPath); Assert.assertEquals("Unexpected number of nodes in path", 2, outPath.getCount());