예제 #1
0
 /**
  * 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;
 }
예제 #2
0
  /**
   * 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;
  }