diff --git a/src/main/java/baritone/bot/pathing/calc/IPath.java b/src/main/java/baritone/bot/pathing/calc/IPath.java index e0eb77f7..7464c9f2 100644 --- a/src/main/java/baritone/bot/pathing/calc/IPath.java +++ b/src/main/java/baritone/bot/pathing/calc/IPath.java @@ -12,6 +12,7 @@ import java.util.List; * @author leijurv */ public interface IPath { + /** * Ordered list of movements to carry out. * movements.get(i).getSrc() should equal positions.get(i) @@ -44,11 +45,13 @@ public interface IPath { } /** - * @param currentPosition - * @return + * Determines whether or not a position is within this path. + * + * @param pos The position to check + * @return Whether or not the specified position is in this class */ - default boolean isInPath(BlockPos currentPosition) { - return positions().contains(currentPosition); + default boolean isInPath(BlockPos pos) { + return positions().contains(pos); } default Tuple closestPathPos(double x, double y, double z) { diff --git a/src/main/java/baritone/bot/pathing/calc/Path.java b/src/main/java/baritone/bot/pathing/calc/Path.java index e13dac25..4a12f475 100644 --- a/src/main/java/baritone/bot/pathing/calc/Path.java +++ b/src/main/java/baritone/bot/pathing/calc/Path.java @@ -14,65 +14,73 @@ import java.util.stream.Collectors; * @author leijurv */ class Path implements IPath { + public final BlockPos start; + public final BlockPos end; + public final Goal goal; + /** * The blocks on the path. Guaranteed that path.get(0) equals start and * path.get(path.size()-1) equals end */ - public final ArrayList path; - final ArrayList movements; + public final List path; + + final List movements; Path(PathNode start, PathNode end, Goal goal) { this.start = start.pos; this.end = end.pos; this.goal = goal; - this.path = new ArrayList<>(); - this.movements = new ArrayList<>(); + this.path = new LinkedList<>(); + this.movements = new LinkedList<>(); assemblePath(start, end); sanityCheck(); } - private final void assemblePath(PathNode start, PathNode end) { + private void assemblePath(PathNode start, PathNode end) { if (!path.isEmpty() || !movements.isEmpty()) { throw new IllegalStateException(); } PathNode current = end; - LinkedList tempPath = new LinkedList<>();//repeatedly inserting to the beginning of an arraylist is O(n^2) - LinkedList tempMovements = new LinkedList<>();//instead, do it into a linked list, then convert at the end + LinkedList tempPath = new LinkedList<>(); // Repeatedly inserting to the beginning of an arraylist is O(n^2) + LinkedList tempMovements = new LinkedList<>(); // Instead, do it into a linked list, then convert at the end while (!current.equals(start)) { tempPath.addFirst(current.pos); tempMovements.addFirst(current.previousMovement); current = current.previous; } tempPath.addFirst(start.pos); - //can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is - //inserting into a LinkedList keeps track of length, then when we addall (which calls .toArray) it's able - //to performantly do that conversion since it knows the length. + // Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is + // inserting into a LinkedList keeps track of length, then when we addall (which calls .toArray) it's able + // to performantly do that conversion since it knows the length. path.addAll(tempPath); movements.addAll(tempMovements); } - public void sanityCheck() { + /** + * Performs a series of checks to ensure that the assembly of the path went as expected. + */ + private void sanityCheck() { if (!start.equals(path.get(0))) { - throw new IllegalStateException(); + throw new IllegalStateException("Start node does not equal first path element"); } if (!end.equals(path.get(path.size() - 1))) { - throw new IllegalStateException(); + throw new IllegalStateException("End node does not equal last path element"); } if (path.size() != movements.size() + 1) { - throw new IllegalStateException(); + throw new IllegalStateException("Size of path array is unexpected"); } for (int i = 0; i < path.size(); i++) { BlockPos src = path.get(i); BlockPos dest = path.get(i + 1); Movement movement = movements.get(i); if (!src.equals(movement.getSrc())) { - throw new IllegalStateException(); + throw new IllegalStateException("Path source is not equal to the movement source"); } if (!dest.equals(movement.getDest())) { - throw new IllegalStateException(); + throw new IllegalStateException("Path destination is not equal to the movement destination"); } } } diff --git a/src/main/java/baritone/bot/pathing/calc/PathNode.java b/src/main/java/baritone/bot/pathing/calc/PathNode.java index ab2cf235..4074b2e7 100644 --- a/src/main/java/baritone/bot/pathing/calc/PathNode.java +++ b/src/main/java/baritone/bot/pathing/calc/PathNode.java @@ -12,19 +12,25 @@ import java.util.Objects; * @author leijurv */ class PathNode { + final BlockPos pos; + final Goal goal; + final double estimatedCostToGoal; // These three fields are mutable and are changed by PathFinder double cost; + PathNode previous; + Movement previousMovement; /** * Is this a member of the open set in A*? (only used during pathfinding) */ boolean isOpen; + /** * In the linked list of open nodes, which one is next? (only used during pathfinding) */ @@ -40,30 +46,28 @@ class PathNode { this.isOpen = false; } - - // TODO possibly reimplement hashCode and equals. They are necessary for this class to function but they could be done better + /** + * TODO: Possibly reimplement hashCode and equals. They are necessary for this class to function but they could be done better + * + * @return The hash code value for this {@link PathNode} + */ @Override - public int hashCode() {//this is some OG code right here + public int hashCode() { int hash = 3241; hash = 3457689 * hash + this.pos.getX(); hash = 8734625 * hash + this.pos.getY(); hash = 2873465 * hash + this.pos.getZ(); - hash = 3241543 * hash + Objects.hashCode(this.goal);//don't call goal.hashcode. this calls objects hashcode to verify that the actual goal objects are == identical, which is important for node caching + // Don't call goal.hashCode(). this calls objects hashcode to verify that the actual goal objects are == identical, which is important for node caching + hash = 3241543 * hash + Objects.hashCode(this.goal); return hash; } @Override - public boolean equals(Object obj) {//autogenerated by netbeans. that's why it looks disgusting. - if (obj == null) { + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof PathNode)) return false; - } - if (getClass() != obj.getClass()) { - return false; - } + final PathNode other = (PathNode) obj; - if (!Objects.equals(this.pos, other.pos)) { - return false; - } - return Objects.equals(this.goal, other.goal); + return Objects.equals(this.pos, other.pos) && Objects.equals(this.goal, other.goal); } }