Пример #1
0
  /*
   * A* Algo from psuedo code from wikipedia
   * http://en.wikipedia.org/wiki/A*_search_algorithm
   */
  private int[] aStar(Node startNode, Node goalNode, int maxLength) {
    ArrayList<Node> closedSet = new ArrayList<Node>();
    PriorityQueue<Node> openSet = new PriorityQueue<Node>();

    // When handling SPNodes
    if (goalNode instanceof SPNode) {
      goalNode = node[startNode.col()];
    }

    int tentativeG;
    Node current;
    boolean tentativeBetter = false;

    // set details of start node
    startNode.g = 0;
    startNode.h = this.heuristicDistance(startNode, goalNode);
    startNode.f = startNode.h;

    // add startNode to openset
    openSet.add(startNode);

    while (!openSet.isEmpty()) {
      current = openSet.poll();
      if (this.reachedGoal(current)) {
        reconstructPath(current);
        return this.toIntArray(this.path);
      }
      closedSet.add(current);
      if (current.g >= maxLength) continue;
      for (Node attached : getDirectlyAttachedNodes(current)) {
        if (closedSet.contains(attached)) continue;
        tentativeG = current.g + 1;
        if (!(openSet.contains(attached))) {
          tentativeBetter = true;
        } else if (tentativeG < attached.g) {
          tentativeBetter = true;
        } else {
          tentativeBetter = false;
        }
        if (tentativeBetter) {
          attached.parent = current;
          attached.g = tentativeG;
          attached.h = heuristicDistance(attached, goalNode);
          attached.f = attached.g + attached.h;
          openSet.add(attached);
        }
      }
    }
    return null;
  }
Пример #2
0
  /**
   * Finds path based on starting and ending points
   *
   * @param oldPath Zombie's existing path
   * @param startX Starting tile x coordinate
   * @param startY Starting tile y coordinate
   * @param targetX Target tile x coordinate
   * @param targetY Target tile y coordinate
   * @return
   */
  public Stack<Node> findPath(
      Stack<Node> oldPath, int startX, int startY, int targetX, int targetY) {
    // If path has the same target do not recalculate path
    if (!oldPath.isEmpty()
        && oldPath.get(0).locationX == targetX
        && oldPath.get(0).locationY == targetY) {
      return oldPath;

    } else {
      // Reset path
      this.path = new Stack<Node>();
      openList.clear();
      closedList.clear();
      path.clear();
      // In case zombie get pushed out of map and has not been updated
      if (startY < 0 || startX < 0 || startY > tiles[0].length || startX > tiles.length)
        return path;

      // Set starting point
      Node start = graph[startY][startX];
      Node currentNode = start;
      openList.add(start);
      int depthOfSearch = 0;
      // If target is unreachable return a empty path
      if (tiles[targetY][targetX] == false)
        // While the frontier is not empty and pathfinder has not
        // exceeded the max number of checks
        while (!openList.isEmpty() && depthOfSearch < MAX_DEPTH) {
          depthOfSearch++;
          // Remove next node from the queue and place into closed
          // list;
          currentNode = openList.peek();
          openList.remove(currentNode);
          closedList.add(currentNode);
          // If current node is the destination create the path
          if (currentNode.locationX == targetX && currentNode.locationY == targetY) {
            while (currentNode != start) {
              path.add(currentNode);
              currentNode = currentNode.prev;
            }
            break;
          }
          // Add adjacent nodes to the frontier
          for (int i = -1; i < 2; i++)
            for (int j = -1; j < 2; j++) {
              // Ignore if out of bounds
              if (currentNode.locationY + i < 0
                  || currentNode.locationX + j < 0
                  || currentNode.locationY + i > tiles.length - 1
                  || currentNode.locationX + j > tiles[0].length - 1) continue;
              // Ignore if tile is solid
              if (tiles[currentNode.locationY + i][currentNode.locationX + j] == true) continue;
              // Ignore if current node
              if (i == 0 && j == 0) continue;

              Node nextNode = graph[currentNode.locationY + i][currentNode.locationX + j];
              int add = 10;
              // Diagonal case
              if (i != 0 && j != 0) {
                add = 14;
                // If any of the two nodes are solid diagonal
                // not possible (zombie would walk through a
                // tile0
                if (tiles[currentNode.locationY + i][currentNode.locationX] == true
                    || tiles[currentNode.locationY][currentNode.locationX + j] == true) continue;
              }
              // If already on the closed list ignore
              if (closedList.contains(nextNode)) continue;
              int g = 0;
              if (currentNode.prev != null) {
                g = currentNode.g;
              }
              g += add;
              // If in the open list movement cost if needed
              if (openList.contains(nextNode)) {
                // If old g is greater than old g, swap it out
                if (nextNode.g > g) {
                  nextNode.g = g;
                  nextNode.setParent(currentNode);
                  ;
                }
                // Else add to open  list
              } else {
                // Set parent to current node
                nextNode.setParent(currentNode);
                nextNode.g = g;
                // Calculate heuristic
                nextNode.h =
                    Math.abs(nextNode.locationX - targetX) + Math.abs(nextNode.locationY - targetY);
                openList.add(nextNode);
              }
            }
        }
    }
    return path;
  }