fix the PathFindingSearch algorithm pathfinding multiple times the same block

This commit is contained in:
Hea3veN 2015-02-14 16:11:45 -03:00
parent 90da2ea4d9
commit efbf47ba49
3 changed files with 55 additions and 18 deletions

View file

@ -34,6 +34,7 @@ public class PathFinding implements IIterableAlgorithm {
private IBlockFilter pathFound; private IBlockFilter pathFound;
private IZone zone; private IZone zone;
private double maxDistanceToEnd = 0; private double maxDistanceToEnd = 0;
private float maxTotalDistance = 0;
private HashMap<BlockIndex, Node> openList = new HashMap<BlockIndex, PathFinding.Node>(); private HashMap<BlockIndex, Node> openList = new HashMap<BlockIndex, PathFinding.Node>();
private HashMap<BlockIndex, Node> closedList = new HashMap<BlockIndex, PathFinding.Node>(); private HashMap<BlockIndex, Node> closedList = new HashMap<BlockIndex, PathFinding.Node>();
@ -65,6 +66,13 @@ public class PathFinding implements IIterableAlgorithm {
maxDistanceToEnd = iMaxDistanceToEnd; maxDistanceToEnd = iMaxDistanceToEnd;
} }
public PathFinding(World iWorld, BlockIndex iStart, BlockIndex iEnd, double iMaxDistanceToEnd,
float iMaxTotalDistance) {
this(iWorld, iStart, iEnd, iMaxDistanceToEnd);
maxTotalDistance = iMaxTotalDistance;
}
@Override @Override
public void iterate() { public void iterate() {
iterate(PATH_ITERATIONS); iterate(PATH_ITERATIONS);
@ -147,6 +155,12 @@ public class PathFinding implements IIterableAlgorithm {
nextNode.totalWeight = nextNode.movementCost + nextNode.destinationCost; nextNode.totalWeight = nextNode.movementCost + nextNode.destinationCost;
if (maxTotalDistance > 0 && nextNode.totalWeight > maxTotalDistance) {
if (!closedList.containsKey(nextNode.index)) {
closedList.put(nextNode.index, nextNode);
}
continue;
}
if (closedList.containsKey(nextNode.index)) { if (closedList.containsKey(nextNode.index)) {
continue; continue;
} else if (openList.containsKey(nextNode.index)) { } else if (openList.containsKey(nextNode.index)) {

View file

@ -32,6 +32,7 @@ public class PathFindingSearch implements IIterableAlgorithm {
private List<PathFinding> pathFinders; private List<PathFinding> pathFinders;
private IBlockFilter pathFound; private IBlockFilter pathFound;
private IZone zone; private IZone zone;
private float maxDistance;
private int searchRadius; private int searchRadius;
private int searchX; private int searchX;
@ -39,11 +40,14 @@ public class PathFindingSearch implements IIterableAlgorithm {
private int searchZ; private int searchZ;
private int searchHeight; private int searchHeight;
public PathFindingSearch(World iWorld, BlockIndex iStart, IBlockFilter iPathFound, float iMaxDistance, IZone iZone) { public PathFindingSearch(World iWorld, BlockIndex iStart, IBlockFilter iPathFound, float iMaxDistance, IZone iZone) {
world = iWorld; world = iWorld;
start = iStart; start = iStart;
pathFound = iPathFound; pathFound = iPathFound;
maxDistance = iMaxDistance;
pathFinders = new LinkedList<PathFinding>(); pathFinders = new LinkedList<PathFinding>();
searchRadius = 1; searchRadius = 1;
searchX = -1; searchX = -1;
@ -67,32 +71,51 @@ public class PathFindingSearch implements IIterableAlgorithm {
int currZ = start.z + searchZ; int currZ = start.z + searchZ;
if (0 <= currY && currY <= searchHeight) { if (0 <= currY && currY <= searchHeight) {
if (isTarget(currX, currY, currZ)) { if (isTarget(currX, currY, currZ)) {
pathFinders.add(new PathFinding(world, start, new BlockIndex(currX, currY, currZ))); pathFinders.add(new PathFinding(world, start, new BlockIndex(currX, currY, currZ), 0, maxDistance));
} }
} }
searchY += 1; nextSearchStep();
if (searchY > searchRadius) {
searchY = -searchRadius;
searchZ += 1;
if (searchZ > searchRadius) {
searchZ = -searchRadius;
searchX += 1;
if (searchX > searchRadius) {
searchRadius += 1;
searchX = -searchRadius;
searchY = -searchRadius;
searchZ = -searchRadius;
}
}
searchHeight = getSearchHeight(start.x + searchX, start.z + searchZ);
}
if (pathFinders.size() >= 5) { if (pathFinders.size() >= 5) {
return; return;
} }
} }
} }
private void nextSearchStep() {
// Step through each block in a hollow cube of size (searchRadius * 2 -1), if done
// add 1 to the radius and start over.
// Step to the next Y
if (Math.abs(searchX) == searchRadius || Math.abs(searchZ) == searchRadius) {
searchY += 1;
} else {
searchY += searchRadius * 2;
}
if (searchY > searchRadius) {
// Step to the next Z
searchY = -searchRadius;
searchZ += 1;
if (searchZ > searchRadius) {
// Step to the next X
searchZ = -searchRadius;
searchX += 1;
if (searchX > searchRadius) {
// Step to the next radius
searchRadius += 1;
searchX = -searchRadius;
searchY = -searchRadius;
searchZ = -searchRadius;
}
}
searchHeight = getSearchHeight(start.x + searchX, start.z + searchZ);
}
}
private boolean isTarget(int x, int y, int z) { private boolean isTarget(int x, int y, int z) {
if (zone != null && !zone.contains(x, y, z)) { if (zone != null && !zone.contains(x, y, z)) {
return false; return false;

View file

@ -39,7 +39,7 @@ public class AIRobotSearchBlock extends AIRobot {
@Override @Override
public void start() { public void start() {
blockScanner = new PathFindingSearch(robot.worldObj, new BlockIndex(robot), pathFound, 64, robot.getZoneToWork()); blockScanner = new PathFindingSearch(robot.worldObj, new BlockIndex(robot), pathFound, 96, robot.getZoneToWork());
blockScannerJob = new IterableAlgorithmRunner(blockScanner, 40000); blockScannerJob = new IterableAlgorithmRunner(blockScanner, 40000);
blockScannerJob.start(); blockScannerJob.start();
} }