package vooga.towerdefense.model; import java.awt.Dimension; import java.awt.Point; import java.util.ArrayList; import util.Location; import vooga.towerdefense.model.AStar.AStar; import vooga.towerdefense.model.AStar.AStarHeuristic; import vooga.towerdefense.model.AStar.AreaMap; import vooga.towerdefense.model.AStar.DiagonalHeuristic; /** * Generates paths based on what tiles are eligible to walk on in the map using * graph algorithms. * * @author JLongley * */ public class Pathfinder { private Tile[][] myGrid; private Dimension myTileSize; public Pathfinder(Tile[][] grid, Dimension tileSize) { myGrid = grid; myTileSize = tileSize; } private static void removeLinearPoints(ArrayList<Point> points) { for (int i = 0; i < points.size() - 2; i++) { if (points.get(i).getX() == points.get(i + 1).getX() && points.get(i + 1).getX() == points.get(i + 2).getX() || points.get(i).getY() == points.get(i + 1).getY() && points.get(i + 1).getY() == points.get(i + 2).getY()) { points.remove(i + 1); i--; } } } /** * Returns a path object corresponding to the shortest path between points * (x1,y1) and (x2,y2) on the map. * * @param x1 * @param y1 * @param x2 * @param y2 * @return the shortest path between (x1,y1) and (x2,y2) */ public Path getShortestPath(Location start, Location finish) { int startX = (int) start.getX(); int startY = (int) start.getY(); int goalX = (int) finish.getX(); int goalY = (int) finish.getY(); int[][] obstacleMap = convertMap(myGrid); AreaMap map = new AreaMap(myGrid[0].length, myGrid.length, obstacleMap); AStarHeuristic heuristic = new DiagonalHeuristic(); AStar aStar = new AStar(map, heuristic); // AreaMap uses transposed map, switch x and y ArrayList<Point> points = aStar.calcShortestPath(startY, startX, goalY, goalX); removeLinearPoints(points); ArrayList<Location> locations = new ArrayList<Location>(); for (Point p : points) locations.add(new Location((p.getY() + .5) * myTileSize.getWidth(), (p.getX() + .5) * myTileSize.getHeight())); return new Path(locations); } private int[][] convertMap(Tile[][] grid) { int[][] obstacleMap = new int[grid.length][grid[0].length]; for (int i = 0; i < myGrid.length; i++) { for (int j = 0; j < myGrid[0].length; j++) { obstacleMap[i][j] = myGrid[i][j].isWalkable() ? 0 : 1; } } return obstacleMap; } }