private MapLocation traceNext(MapLocation currentLoc, Direction faceDir, boolean cw) { // Put isTraversable first so that the second while loop will rotate the // direction to walkable position // Try code reuse in the future int step = 0; if (cw) { while (isTraversable(currentLoc.add(faceDir)) && step < 8) { faceDir = faceDir.rotateRight(); step++; } step = 0; while (!isTraversable(currentLoc.add(faceDir)) && step < 8) { faceDir = faceDir.rotateLeft(); step++; } } else { while (isTraversable(currentLoc.add(faceDir)) && step < 8) { faceDir = faceDir.rotateLeft(); step++; } step = 0; while (!isTraversable(currentLoc.add(faceDir)) && step < 8) { faceDir = faceDir.rotateRight(); step++; } } return currentLoc.add(faceDir); }
private boolean betterTracingWay(MapLocation s, MapLocation t) { MapLocation[] tracingLoc = new MapLocation[2]; Direction[] tracingDir = new Direction[2]; int[] tracingcost = new int[2]; int tracingIndex; Direction nextDir, startTracingDir; MapLocation nextLoc; Direction faceDir = controllers.myRC.getDirection(); Direction desDir = s.directionTo(t); tracingLoc[0] = traceNext(s, desDir, true); tracingLoc[1] = traceNext(s, desDir, false); tracingDir[0] = s.directionTo(tracingLoc[0]); tracingDir[1] = s.directionTo(tracingLoc[0]); tracingcost[0] = computeCost(0, faceDir, tracingDir[0]); tracingcost[1] = computeCost(0, faceDir, tracingDir[1]); do { if (tracingcost[0] <= tracingcost[1]) { tracingIndex = 0; startTracingDir = tracingDir[0].rotateRight().rotateRight(); nextLoc = traceNext(tracingLoc[0], startTracingDir, true); } else { tracingIndex = 1; startTracingDir = tracingDir[1].rotateLeft().rotateLeft(); nextLoc = traceNext(tracingLoc[1], startTracingDir, false); } nextDir = tracingLoc[tracingIndex].directionTo(nextLoc); desDir = tracingLoc[tracingIndex].directionTo(t); ; if (isOpen( tracingLoc[tracingIndex], tracingDir[tracingIndex], nextDir, desDir, tracingIndex == 0) && isTraversable(tracingLoc[tracingIndex].add(desDir))) { return tracingIndex == 0; } else { tracingcost[tracingIndex] = computeCost(tracingcost[tracingIndex], tracingDir[tracingIndex], nextDir); tracingDir[tracingIndex] = nextDir; tracingLoc[tracingIndex] = nextLoc; } } while (true); }
public Direction Bug(MapLocation s, MapLocation t, int tolerance) { // arrive the destination if (s.distanceSquaredTo(t) <= tolerance) { reset(); return Direction.OMNI; } Direction nextDir; Direction faceDir = controllers.myRC.getDirection(); // if target is not traversable, back-tracing the destination while (!isTraversable(t)) { nextDir = s.directionTo(t); t = t.subtract(nextDir); // beside the source if (s.distanceSquaredTo(t) <= tolerance) { reset(); return Direction.OMNI; } } modifiedDes = t; Direction desDir = s.directionTo(t); MapLocation nextLoc; if (isTracing) { Direction startTracingDir = isCW ? faceDir.rotateRight().rotateRight() : faceDir.rotateLeft().rotateLeft(); nextLoc = traceNext(s, startTracingDir, isCW); nextDir = s.directionTo(nextLoc); // The way is open if (isOpen(s, faceDir, nextDir, desDir, isCW) && isTraversable(s.add(desDir))) { isTracing = false; return desDir; } return nextDir; } else { if (isTraversable(s.add(desDir))) { return desDir; } else { isTracing = true; isCW = betterTracingWay(s, t); nextLoc = traceNext(s, desDir, isCW); return s.directionTo(nextLoc); } } }
private boolean isOpen( MapLocation currentLoc, Direction currentDir, Direction nextDir, Direction desDir, boolean cw) { if (desDir == Direction.OMNI) { return true; } if (!isTraversable(currentLoc.add(currentDir))) return false; if (cw) { while (currentDir != nextDir) { if (currentDir == desDir) return true; currentDir = currentDir.rotateRight(); } } else { while (currentDir != nextDir) { if (currentDir == desDir) return true; currentDir = currentDir.rotateLeft(); } } return (nextDir == desDir); }
public void setDestination(MapLocation loc) { if (loc.equals(destination)) return; else { reset(); destination = new MapLocation(loc.x, loc.y); modifiedDes = new MapLocation(loc.x, loc.y); } }
public MapLocation getNextJumpingLocTowardDes(int tolerance) { MapLocation currentLoc = controllers.myRC.getLocation(); MapLocation jumpLoc = controllers.myRC.getLocation(); MapLocation nextLoc = jumpLoc; Direction nextDir; do { jumpLoc = nextLoc; if (jumpLoc.distanceSquaredTo(destination) < tolerance && isTraversable(jumpLoc)) { // controllers.myRC.setIndicatorString(2, "here: " + jumpLoc + ", des" + destination); return jumpLoc; } nextDir = jumpLoc.directionTo(destination); nextLoc = nextLoc.add(nextDir); } while (currentLoc.distanceSquaredTo(nextLoc) <= 16); // controllers.myRC.setIndicatorString(2, "optimal jump to: " + jumpLoc); // Find alternative jumping location if (!isTraversable(jumpLoc)) { while (!jumpLoc.isAdjacentTo(currentLoc)) { MapLocation temp = jumpLoc; MapLocation best = null; int distance = currentLoc.distanceSquaredTo(destination); for (int i = 0; i < 8; i++) { temp = jumpLoc.add(Util.dirs[i]); if (currentLoc.distanceSquaredTo(temp) <= 16 && isTraversable(temp) && temp.distanceSquaredTo(destination) < distance) { best = temp; distance = temp.distanceSquaredTo(destination); } } if (best != null) { return best; } else { jumpLoc = jumpLoc.subtract(currentLoc.directionTo(jumpLoc)); } } } if (jumpLoc.isAdjacentTo(currentLoc) || jumpLoc.equals(currentLoc)) return null; return jumpLoc; }
public MapLocation getNextJumpingLoc(int tolerance) { MapLocation jumpLoc = controllers.myRC.getLocation(); MapLocation currentLoc = controllers.myRC.getLocation(); Direction desDir = currentLoc.directionTo(destination); MapLocation nextLoc = controllers.myRC.getLocation(); Direction nextDir = controllers.myRC.getDirection(); Direction startTracingDir; if (jumpingTracing) { // controllers.myRC.setIndicatorString(2, "tracing"); startTracingDir = isCW ? nextDir.rotateRight().rotateRight() : nextDir.rotateLeft().rotateLeft(); nextLoc = currentLoc.add(startTracingDir, 2); do { if (isTraversable(nextLoc)) jumpLoc = nextLoc; nextLoc = nextLoc.add(startTracingDir); } while (currentLoc.distanceSquaredTo(nextLoc) <= 16); if (currentLoc.distanceSquaredTo(currentLoc) > 2) { jumpingTracing = false; // controllers.myRC.setIndicatorString(2, "Find good jumpLoc: " + jumpLoc); return jumpLoc; } nextLoc = currentLoc; nextDir = controllers.myRC.getDirection(); // if( controllers.myRC.senseTerrainTile(currentLoc.add(startTracingDir)) == // TerrainTile.OFF_MAP ){ // isCW = !isCW; // nextDir = nextDir.opposite(); // } // controllers.myRC.setIndicatorString(2, "Do the bugging"); Direction faceDir; do { jumpLoc = nextLoc; faceDir = nextDir; startTracingDir = isCW ? nextDir.rotateRight().rotateRight() : nextDir.rotateLeft().rotateLeft(); nextLoc = traceNext(jumpLoc, startTracingDir, isCW); nextDir = jumpLoc.directionTo(nextLoc); desDir = jumpLoc.directionTo(destination); if (isOpen(jumpLoc, faceDir, nextDir, desDir, isCW) && isTraversable(jumpLoc.add(desDir))) { // controllers.myRC.setIndicatorString(2, "Open"); jumpingTracing = false; nextLoc = jumpLoc; if (jumpLoc.distanceSquaredTo(currentLoc) <= 2) return null; return jumpLoc; } } while (currentLoc.distanceSquaredTo(nextLoc) <= 16); if (jumpLoc.distanceSquaredTo(currentLoc) <= 2) return null; return jumpLoc; } else { // controllers.myRC.setIndicatorString(2, "go"); jumpLoc = getNextJumpingLocTowardDes(tolerance); if (jumpLoc == null) { // controllers.myRC.setIndicatorString(2, "No way to go"); if (isTraversable(currentLoc.add(desDir))) isCW = betterTracingWay(currentLoc.add(desDir), destination); else isCW = betterTracingWay(currentLoc, destination); jumpingTracing = true; } } return jumpLoc; }