/** * Finds and returns the closest point containing a city to the given point. Does not include * provided point as a possible city location. * * <p>If there are no cities, null is returned. * * @param point * @return */ public Coord closestCity(Coord point) { double dist = 999999999, newdist; Coord closest = null; for (Coord c : cities) { if (c.equals(point)) { continue; // skip the one being tested for } newdist = Math.pow(point.x - c.x, 2) + Math.pow(point.y - c.y, 2); if (newdist < dist) { dist = newdist; closest = c; } } return closest; }
/** * Finds an A* path to the target from the start. If no path is possible, returns null. * * @param startx the x coordinate of the start location * @param starty the y coordinate of the start location * @param targetx the x coordinate of the target location * @param targety the y coordinate of the target location * @return the shortest path, or null */ public Queue<Coord> path(int startx, int starty, int targetx, int targety) { start = Coord.get(startx, starty); target = Coord.get(targetx, targety); open.clear(); finished = new boolean[width][height]; parent = new Coord[width][height]; Direction[] dirs; switch (type) { case MANHATTAN: dirs = Direction.CARDINALS; break; case CHEBYSHEV: case EUCLIDEAN: case DIJKSTRA: default: dirs = Direction.OUTWARDS; break; } Coord p = start; open.add(p); while (!p.equals(target)) { finished[p.x][p.y] = true; open.remove(p); for (Direction dir : dirs) { int x = p.x + dir.deltaX; if (x < 0 || x >= width) { continue; // out of bounds so skip ahead } int y = p.y + dir.deltaY; if (y < 0 || y >= height) { continue; // out of bounds so skip ahead } if (!finished[x][y]) { Coord test = Coord.get(x, y); if (open.contains(test)) { double parentG = g(parent[x][y].x, parent[x][y].y); if (parentG < 0) { continue; // not a valid point so skip ahead } double g = g(p.x, p.y); if (g < 0) { continue; // not a valid point so skip ahead } if (parent[x][y] == null || parentG > g) { parent[x][y] = p; } } else { open.add(test); parent[x][y] = p; } } } p = smallestF(); if (p == null) { return null; // no path possible } } Deque<Coord> deq = new ArrayDeque<>(); while (!p.equals(start)) { deq.offerFirst(p); p = parent[p.x][p.y]; } return deq; }