/** * Determine if x and y need to be incremented or decremented. * * @param node * @return an int array of size two whose values should be added to x and y in order to move * diagonally. */ public int[] stepDiagonally(Node node) { int[] step; switch (node.direction) { case 1: // NE step = new int[] { NavTools.distanceLeft(node.location[0], node.location[1], map.mapY), NavTools.distanceLeft(node.location[0], node.location[1], map.mapX) }; break; case 3: // SE step = new int[] {1, 1}; break; case 5: // SW step = new int[] {-1, 1}; break; default: // NW step = new int[] {-1, -1}; break; } return step; }
public Node getPath(int[] a, int[] b) { q = new Queue(a, b); while (q.front != null) { // while the queue is not empty Node next = q.pop(); // pop the top node on the queue // current position on the diagonal of the next Node int[] location = new int[] {next.location[0], next.location[1]}; // distances from location to next void (x = step[0], y = step[1]) int[] step = new int[2]; // previous distances int[] lastStep; switch (next.direction) { // determine the direction of movement case 1: // direction = NE // initialize as the distance from this node to x and y voids lastStep = new int[] { NavTools.distanceRight(location[0], location[1], map.mapX), NavTools.distanceLeft(location[1], location[0], map.mapY) }; while (lastStep[0] != 0) { // while the current location is walkable // check if the goal is directly reachable from this location if (q.goal[0] == location[0]) { if (q.goal[1] <= location[1] && q.goal[1] >= location[1] - NavTools.distanceLeft(location[1], location[0], map.mapY)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } else if (q.goal[1] >= location[1] && q.goal[1] <= location[1] + NavTools.distanceRight(location[1], location[0], map.mapY)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } } else if (q.goal[1] == location[1]) { if (q.goal[0] <= location[0] && q.goal[0] >= location[0] - NavTools.distanceLeft(location[0], location[1], map.mapX)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } else if (q.goal[0] >= location[0] && q.goal[0] <= location[0] + NavTools.distanceRight(location[0], location[1], map.mapX)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } } // step = distances to x and y voids & properly increment/decrement location step[0] = NavTools.distanceRight(++location[0], --location[1], map.mapX); step[1] = NavTools.distanceLeft(location[1], location[0], map.mapY); // difference between last and current distances int dX = step[0] - lastStep[0]; // should be -1 if (dX >= 0) { // if x difference is greater than -1 // check the number of consecutive voids at x-1+distanceRight, y-1 int voids = NavTools.distanceVoidRight( location[0] + lastStep[0] - 1, location[1] + 1, map.mapX); // if the new difference is greater than 0, add a new Node to the queue if (dX - voids >= -1) { // new direction is SE q.offer( new int[] {location[0] + voids + lastStep[0] - 2, location[1]}, 3, new int[] {location[0], location[1]}, next); } } else if (dX < -1) { // if x difference is less than -1 // check the number of consecutive voids at x-1+distanceRight, y-1 int voids = NavTools.distanceVoidRight(location[0] + step[0], location[1], map.mapX); // if the new difference is greater than or equal to 0, add a new Node to the queue if (dX + voids < 0) { // new direction is NE q.offer( new int[] {location[0] + voids + step[0] - 1, location[1] + 1}, 1, new int[] {location[0] - 1, location[1] + 1}, next); } } int dY = step[1] - lastStep[1]; // should be -1 if (dY >= 0) { // if y difference is greater than -1 // check the number of consecutive voids int voids = NavTools.distanceVoidLeft( location[1] - lastStep[1] + 1, location[0] - 1, map.mapY); // if the new difference is greater than 0, add a new Node to the queue if (dY - voids >= -1) { // new direction is SE, need two waypoints q.offer( new int[] {location[0], location[1] - voids - lastStep[1] + 2}, 7, new int[] {location[0], location[1]}, next); } } else if (dY < -1) { // if y difference is less than -1 // check the number of consecutive voids at int voids = NavTools.distanceVoidLeft(location[1] - step[1], location[0], map.mapY); // if the new difference is greater than or equal to 0, add a new Node to the queue if (dY + voids < 0) { // new direction is NW, need two waypoints q.offer( new int[] {location[0] - 1, location[1] - voids - step[1] + 1}, 1, new int[] {location[0] - 1, location[1] + 1}, next); } } lastStep[0] = step[0]; lastStep[1] = step[1]; } break; case 3: // direction = SE // initialize as the distance from this node to x and y voids lastStep = new int[] { NavTools.distanceRight(location[0], location[1], map.mapX), NavTools.distanceRight(location[1], location[0], map.mapY) }; while (lastStep[0] != 0) { // while the current location is walkable // check if the goal is directly reachable from this location if (q.goal[0] == location[0]) { if (q.goal[1] <= location[1] && q.goal[1] >= location[1] - NavTools.distanceLeft(location[1], location[0], map.mapY)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } else if (q.goal[1] >= location[1] && q.goal[1] <= location[1] + NavTools.distanceRight(location[1], location[0], map.mapY)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } } else if (q.goal[1] == location[1]) { if (q.goal[0] <= location[0] && q.goal[0] >= location[0] - NavTools.distanceLeft(location[0], location[1], map.mapX)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } else if (q.goal[0] >= location[0] && q.goal[0] <= location[0] + NavTools.distanceRight(location[0], location[1], map.mapX)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } } // step = distances to x and y voids & properly increment/decrement location step[0] = NavTools.distanceRight(++location[0], ++location[1], map.mapX); step[1] = NavTools.distanceRight(location[1], location[0], map.mapY); // difference between last and current distances int dX = step[0] - lastStep[0]; // should be -1 if (dX >= 0) { // if x difference is greater than -1 // check the number of consecutive voids at x-1+distanceRight, y-1 int voids = NavTools.distanceVoidRight( location[0] + lastStep[0] - 1, location[1] - 1, map.mapX); // if the new difference is greater than 0, add a new Node to the queue if (dX - voids >= -1) { // new direction is SE q.offer( new int[] {location[0] + voids + lastStep[0] - 2, location[1]}, 1, new int[] {location[0], location[1]}, next); } } else if (dX < -1) { // if x difference is less than -1 // check the number of consecutive voids at x-1+distanceRight, y-1 int voids = NavTools.distanceVoidRight(location[0] + step[0], location[1], map.mapX); // if the new difference is greater than or equal to 0, add a new Node to the queue if (dX + voids < 0) { // new direction is NE q.offer( new int[] {location[0] + voids + step[0] - 1, location[1] - 1}, 3, new int[] {location[0] - 1, location[1] - 1}, next); } } int dY = step[1] - lastStep[1]; // should be -1 if (dY >= 0) { // if y difference is greater than -1 // check the number of consecutive voids int voids = NavTools.distanceVoidRight( location[1] + lastStep[1] - 1, location[0] - 1, map.mapY); // if the new difference is greater than 0, add a new Node to the queue if (dY - voids >= -1) { // new direction is SE, need two waypoints q.offer( new int[] {location[0], location[1] + voids + lastStep[1] - 2}, 5, new int[] {location[0], location[1]}, next); } } else if (dY < -1) { // if y difference is less than -1 // check the number of consecutive voids at int voids = NavTools.distanceVoidRight(location[1] + step[1], location[0], map.mapY); // if the new difference is greater than or equal to 0, add a new Node to the queue if (dY + voids < 0) { // new direction is NW, need two waypoints q.offer( new int[] {location[0] - 1, location[1] + voids + step[1] - 1}, 3, new int[] {location[0] - 1, location[1] - 1}, next); } } lastStep[0] = step[0]; lastStep[1] = step[1]; } break; case 5: // direction = SW // initialize as the distance from this node to x and y voids lastStep = new int[] { NavTools.distanceLeft(location[0], location[1], map.mapX), NavTools.distanceRight(location[1], location[0], map.mapY) }; while (lastStep[0] != 0) { // while the current location is walkable // check if the goal is directly reachable from this location if (q.goal[0] == location[0]) { if (q.goal[1] <= location[1] && q.goal[1] >= location[1] - NavTools.distanceLeft(location[1], location[0], map.mapY)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } else if (q.goal[1] >= location[1] && q.goal[1] <= location[1] + NavTools.distanceRight(location[1], location[0], map.mapY)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } } else if (q.goal[1] == location[1]) { if (q.goal[0] <= location[0] && q.goal[0] >= location[0] - NavTools.distanceLeft(location[0], location[1], map.mapX)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } else if (q.goal[0] >= location[0] && q.goal[0] <= location[0] + NavTools.distanceRight(location[0], location[1], map.mapX)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } } // step = distances to x and y voids & properly increment/decrement location step[0] = NavTools.distanceLeft(--location[0], ++location[1], map.mapX); step[1] = NavTools.distanceRight(location[1], location[0], map.mapY); // difference between last and current distances int dX = step[0] - lastStep[0]; // should be -1 if (dX >= 0) { // if x difference is greater than -1 // check the number of consecutive voids at x-1+distanceRight, y-1 int voids = NavTools.distanceVoidLeft( location[0] - lastStep[0] + 1, location[1] - 1, map.mapX); // if the new difference is greater than 0, add a new Node to the queue if (dX - voids >= -1) { // new direction is NW q.offer( new int[] {location[0] - voids - lastStep[0] + 2, location[1]}, 7, new int[] {location[0], location[1]}, next); } } else if (dX < -1) { // if x difference is less than -1 // check the number of consecutive voids at x-1+distanceRight, y-1 int voids = NavTools.distanceVoidLeft(location[0] - step[0], location[1], map.mapX); // if the new difference is greater than or equal to 0, add a new Node to the queue if (dX + voids < 0) { // new direction is NE q.offer( new int[] {location[0] - voids - step[0] + 1, location[1] - 1}, 3, new int[] {location[0] + 1, location[1] - 1}, next); } } int dY = step[1] - lastStep[1]; // should be -1 if (dY >= 0) { // if y difference is greater than -1 // check the number of consecutive voids int voids = NavTools.distanceVoidRight( location[1] + lastStep[1] - 1, location[0] + 1, map.mapY); // if the new difference is greater than 0, add a new Node to the queue if (dY - voids >= -1) { // new direction is SE, need two waypoints q.offer( new int[] {location[0], location[1] + voids + lastStep[1] - 2}, 5, new int[] {location[0], location[1]}, next); } } else if (dY < -1) { // if y difference is less than -1 // check the number of consecutive voids at int voids = NavTools.distanceVoidRight(location[1] + step[1], location[0], map.mapY); // if the new difference is greater than or equal to 0, add a new Node to the queue if (dY + voids < 0) { // new direction is NW, need two waypoints q.offer( new int[] {location[0] + 1, location[1] + voids + step[1] - 1}, 3, new int[] {location[0] + 1, location[1] - 1}, next); } } lastStep[0] = step[0]; lastStep[1] = step[1]; } break; default: // direction = NW // initialize as the distance from this node to x and y voids lastStep = new int[] { NavTools.distanceLeft(location[0], location[1], map.mapX), NavTools.distanceRight(location[1], location[0], map.mapY) }; while (lastStep[0] != 0) { // while the current location is walkable // check if the goal is directly reachable from this location if (q.goal[0] == location[0]) { if (q.goal[1] <= location[1] && q.goal[1] >= location[1] - NavTools.distanceLeft(location[1], location[0], map.mapY)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } else if (q.goal[1] >= location[1] && q.goal[1] <= location[1] + NavTools.distanceRight(location[1], location[0], map.mapY)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } } else if (q.goal[1] == location[1]) { if (q.goal[0] <= location[0] && q.goal[0] >= location[0] - NavTools.distanceLeft(location[0], location[1], map.mapX)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } else if (q.goal[0] >= location[0] && q.goal[0] <= location[0] + NavTools.distanceRight(location[0], location[1], map.mapX)) { next.mapNext = new Node(q.goal, location, next, 0, 0); next.mapNext.mapLast = next; return q.retrace(next); } } // step = distances to x and y voids & properly increment/decrement location step[0] = NavTools.distanceLeft(--location[0], --location[1], map.mapX); step[1] = NavTools.distanceLeft(location[1], location[0], map.mapY); // difference between last and current distances int dX = step[0] - lastStep[0]; // should be -1 if (dX >= 0) { // if x difference is greater than -1 // check the number of consecutive voids at x-1+distanceRight, y-1 int voids = NavTools.distanceVoidLeft( location[0] - lastStep[0] + 1, location[1] + 1, map.mapX); // if the new difference is greater than 0, add a new Node to the queue if (dX - voids >= -1) { // new direction is NW q.offer( new int[] {location[0] - voids - lastStep[0] + 2, location[1]}, 5, new int[] {location[0], location[1]}, next); } } else if (dX < -1) { // if x difference is less than -1 // check the number of consecutive voids at x-1+distanceRight, y-1 int voids = NavTools.distanceVoidLeft(location[0] - step[0], location[1], map.mapX); // if the new difference is greater than or equal to 0, add a new Node to the queue if (dX + voids < 0) { // new direction is NE q.offer( new int[] {location[0] - voids - step[0] + 1, location[1] + 1}, 7, new int[] {location[0] + 1, location[1] + 1}, next); } } int dY = step[1] - lastStep[1]; // should be -1 if (dY >= 0) { // if y difference is greater than -1 // check the number of consecutive voids int voids = NavTools.distanceVoidLeft( location[1] - lastStep[1] + 1, location[0] + 1, map.mapY); // if the new difference is greater than 0, add a new Node to the queue if (dY - voids >= -1) { // new direction is SE, need two waypoints q.offer( new int[] {location[0], location[1] - voids - lastStep[1] + 2}, 1, new int[] {location[0], location[1]}, next); } } else if (dY < -1) { // if y difference is less than -1 // check the number of consecutive voids at int voids = NavTools.distanceVoidLeft(location[1] - step[1], location[0], map.mapY); // if the new difference is greater than or equal to 0, add a new Node to the queue if (dY + voids < 0) { // new direction is NW, need two waypoints q.offer( new int[] {location[0] + 1, location[1] - voids - step[1] + 1}, 7, new int[] {location[0] + 1, location[1] + 1}, next); } } lastStep[0] = step[0]; lastStep[1] = step[1]; } break; } } return null; }