diff --git a/src/main/java/baritone/bot/pathing/calc/IPath.java b/src/main/java/baritone/bot/pathing/calc/IPath.java index b642b38a..57d6cb01 100644 --- a/src/main/java/baritone/bot/pathing/calc/IPath.java +++ b/src/main/java/baritone/bot/pathing/calc/IPath.java @@ -8,6 +8,9 @@ import net.minecraft.util.math.BlockPos; import java.util.Collection; import java.util.List; +/** + * @author leijurv + */ public interface IPath { /** * Ordered list of movements to carry out. diff --git a/src/main/java/baritone/bot/pathing/calc/Path.java b/src/main/java/baritone/bot/pathing/calc/Path.java new file mode 100644 index 00000000..e945c599 --- /dev/null +++ b/src/main/java/baritone/bot/pathing/calc/Path.java @@ -0,0 +1,70 @@ +package baritone.bot.pathing.calc; + +import baritone.bot.pathing.goals.Goal; +import baritone.bot.pathing.movements.Movement; +import net.minecraft.util.math.BlockPos; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +/** + * A node based implementation of IPath + * + * @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; + + 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<>(); + assemblePath(start, end); + } + + private final void assemblePath(PathNode start, PathNode end) { + 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 + while (!current.equals(start)) { + tempPath.addFirst(current.pos); + tempMovements.addFirst(current.previousMovement); + current = current.previous; + } + tempPath.addFirst(start.pos); + path.addAll(tempPath); + movements.addAll(tempMovements); + } + + @Override + public List movements() { + return movements; + } + + @Override + public List positions() { + return path; + } + + @Override + public Collection getBlocksToMine() { + return null; + } + + @Override + public Collection getBlocksToPlace() { + return null; + } +} \ No newline at end of file diff --git a/src/main/resources/baritone/pathfinding/Node.java b/src/main/java/baritone/bot/pathing/calc/PathNode.java similarity index 58% rename from src/main/resources/baritone/pathfinding/Node.java rename to src/main/java/baritone/bot/pathing/calc/PathNode.java index 63f910b2..02bd5c04 100644 --- a/src/main/resources/baritone/pathfinding/Node.java +++ b/src/main/java/baritone/bot/pathing/calc/PathNode.java @@ -1,32 +1,47 @@ -package baritone.pathfinding; +package baritone.bot.pathing.calc; -import baritone.pathfinding.goals.Goal; -import baritone.pathfinding.actions.Action; -import java.util.Objects; +import baritone.bot.pathing.goals.Goal; +import baritone.bot.pathing.movements.Movement; import net.minecraft.util.math.BlockPos; +import java.util.Objects; + /** + * A node in the path, containing the cost and steps to get to it. * * @author leijurv */ -public class Node { +class PathNode { final BlockPos pos; - double cost; - Node previous; final Goal goal; final double estimatedCostToGoal; - Action previousAction; + + // 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; - Node nextOpen; - public Node(BlockPos pos, Goal goal) { + /** + * In the linked list of open nodes, which one is next? (only used during pathfinding) + */ + PathNode nextOpen; + + public PathNode(BlockPos pos, Goal goal) { this.pos = pos; this.previous = null; this.cost = Short.MAX_VALUE; this.goal = goal; this.estimatedCostToGoal = goal.heuristic(pos); - this.previousAction = null; + this.previousMovement = null; this.isOpen = false; } + + + // TODO possibly reimplement hashCode and equals. They are necessary for this class to function but they could be done better @Override public int hashCode() {//this is some OG code right here int hash = 3241; @@ -36,6 +51,7 @@ public class Node { 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) { @@ -44,7 +60,7 @@ public class Node { if (getClass() != obj.getClass()) { return false; } - final Node other = (Node) obj; + final PathNode other = (PathNode) obj; if (!Objects.equals(this.pos, other.pos)) { return false; } diff --git a/src/main/resources/baritone/util/Out.java b/src/main/resources/baritone/util/Out.java index bc844178..926d3d69 100644 --- a/src/main/resources/baritone/util/Out.java +++ b/src/main/resources/baritone/util/Out.java @@ -78,7 +78,7 @@ public class Out { * Out.mode is Debug or Ludicrous. Do not use a Mode.None or a * Mode.Ludicrous in this parameter. * @exception IllegalArgumentException This will only be triggered if a - * messages given with a req of Node or Ludicrous + * messages given with a req of PathNode or Ludicrous */ public static void gui(Object o, Mode req) throws IllegalArgumentException { if (req.equals(Mode.None) || req.equals(Mode.Ludicrous)) {