package com.bioxx.jmapgen.pathfinding.dungeon; import java.util.Vector; import com.bioxx.jmapgen.IslandMap; import com.bioxx.jmapgen.Point; import com.bioxx.jmapgen.graph.Center; import com.bioxx.jmapgen.graph.Center.Marker; public class PathFinder { IslandMap map; public PathFinder(IslandMap m) { map = m; } public Path findPath(Center start, Center end) { Vector<PathNode> reachable = new Vector<PathNode>(); Vector<Center> explored = new Vector<Center>(); reachable.add(new PathNode(start, 0)); while(!reachable.isEmpty()) { PathNode node = choose_node(reachable, end); Center c = node.center; if(c == end) { return buildPath(node); } explored.add(c); reachable.remove(node); Vector<PathNode> newReachable = new Vector<PathNode>(); for(Center n : c.neighbors) { if(!explored.contains(n) && !n.hasAnyMarkersOf(Marker.Water, Marker.Border, Marker.Ocean, Marker.Coast, Marker.Lava)) newReachable.add(new PathNode(n, Integer.MAX_VALUE)); } for(PathNode n : newReachable) { if(!reachable.contains(n)) reachable.add(n); if(node.nodeCost + n.transitCost < n.nodeCost) { n.prev = node; n.nodeCost = node.nodeCost + n.transitCost; } } } return null; } private Path buildPath(PathNode endNode) { Path p = new Path(); p.addNode(endNode); PathNode pn = endNode.prev; while(pn != null) { p.addNode(pn); pn = pn.prev; } return p; } private PathNode choose_node(Vector<PathNode>reachable, Center end) { int min_cost = Integer.MAX_VALUE; PathNode best_node = null; for(PathNode node : reachable) { int cost_start_to_node = node.nodeCost; int cost_node_to_goal = estimateDistance(node.center.point, end.point); int total_cost = cost_start_to_node + cost_node_to_goal; if( min_cost > total_cost) { min_cost = total_cost; best_node = node; } } return best_node; } private int estimateDistance(Point p0, Point p1) { return (int)Math.floor(Math.sqrt( Math.pow((p0.x - p1.x),2) + Math.pow((p0.y - p1.y),2))); } }