/**
  * Follow the waypoint stored in currentWaypoint
  *
  * @param defuseMines whether or not to defuse mines while following waypoints
  * @throws GameActionException
  */
 public static void followWaypoints(boolean defuseMines, boolean swarm)
     throws GameActionException {
   // If we're close to currentWaypoint, find the next one
   if (rc.getLocation().distanceSquaredTo(destination) <= Constants.PATH_GO_ALL_IN_SQ_RADIUS) {
     // Stop nav-ing?
     navMode = NavMode.REGULAR;
     // We're done following waypoints
     if (defuseMines) {
       goToLocation(destination);
     } else {
       goToLocationAvoidMines(destination);
     }
   } else if (rc.getLocation().distanceSquaredTo(currentWaypoint)
       <= Constants.WAYPOINT_SQUARED_DISTANCE_CHECK) {
     // We're close to currentWaypoint, so find the next one
     switch (navMode) {
       case SMART:
         getSmartWaypoint();
         break;
       case BACKDOOR:
         getBackdoorWaypoint();
         break;
       default:
         break;
     }
     if (defuseMines) {
       if (swarm) {
         //					rc.setIndicatorString(2, currentWaypoint.toString());
         goToLocationSwarm(currentWaypoint, true);
       } else {
         goToLocation(currentWaypoint);
       }
     } else {
       if (swarm) {
         goToLocationSwarm(currentWaypoint, false);
       } else {
         goToLocationAvoidMines(currentWaypoint);
       }
     }
   } else {
     // Keep moving to the current waypoint
     if (defuseMines) {
       if (swarm) {
         //					rc.setIndicatorString(2, currentWaypoint.toString());
         goToLocationSwarm(currentWaypoint, true);
       } else {
         goToLocation(currentWaypoint);
       }
     } else {
       if (swarm) {
         goToLocationSwarm(currentWaypoint, false);
       } else {
         goToLocationAvoidMines(currentWaypoint);
       }
     }
   }
 }
 /**
  * Sets up the backdoor navigation system for a given endLocation.
  *
  * @param endLocation
  * @throws GameActionException
  */
 public static void setupBackdoorNav(MapLocation endLocation) throws GameActionException {
   navMode = NavMode.BACKDOOR;
   destination = endLocation;
   // Calculate all the waypoints first and save them (this is different from smart nav)
   MapLocation currentLocation = rc.getLocation();
   Direction dirToEndLocation = currentLocation.directionTo(endLocation);
   // How close are we to the wall?
   int horzDistanceToWall = mapWidth / 2 - Math.abs(endLocation.x - mapCenter.x);
   int vertDistanceToWall = mapHeight / 2 - Math.abs(endLocation.y - mapCenter.y);
   int distanceToWall = (int) (0.8 * Math.min(horzDistanceToWall, vertDistanceToWall));
   MapLocation firstWaypoint = currentLocation.add(dirToEndLocation, -distanceToWall);
   MapLocation lastWaypoint = endLocation.add(dirToEndLocation, distanceToWall);
   backdoorWaypoints = new MapLocation[] {firstWaypoint, null, null, lastWaypoint};
   // Now let's try to find some intermediate waypoints to follow
   // Let's see if we should move horizontally first or vertically first
   int dx = endLocation.x - currentLocation.x;
   int dy = endLocation.y - currentLocation.y;
   if (Math.abs(dx) > Math.abs(dy)) {
     // We're vertically really close, but not horizontally, so move vertically first
     if (Util.Random() < 0.5) {
       // Try moving up, then horizontally, then down to endLocation
       backdoorWaypoints[1] = new MapLocation(currentLocation.x, Constants.BACKDOOR_WALL_BUFFER);
       // We need to know if endLocation is closer to the left wall or the right wall
       if (endLocation.x < mapWidth - endLocation.x) { // left wall
         backdoorWaypoints[2] =
             new MapLocation(Constants.BACKDOOR_WALL_BUFFER, Constants.BACKDOOR_WALL_BUFFER);
       } else { // right wall
         backdoorWaypoints[2] =
             new MapLocation(
                 mapWidth - 1 - Constants.BACKDOOR_WALL_BUFFER, Constants.BACKDOOR_WALL_BUFFER);
       }
     } else {
       // Try moving down, then horizontally, then up to endLocation
       backdoorWaypoints[1] =
           new MapLocation(currentLocation.x, mapHeight - Constants.BACKDOOR_WALL_BUFFER);
       // We need to know if endLocation is closer to the left wall or the right wall
       if (endLocation.x < mapWidth - endLocation.x) { // left wall
         backdoorWaypoints[2] =
             new MapLocation(
                 Constants.BACKDOOR_WALL_BUFFER, mapHeight - 1 - Constants.BACKDOOR_WALL_BUFFER);
       } else { // right wall
         backdoorWaypoints[2] =
             new MapLocation(
                 mapWidth - 1 - Constants.BACKDOOR_WALL_BUFFER,
                 mapHeight - 1 - Constants.BACKDOOR_WALL_BUFFER);
       }
     }
   } else {
     // We're horizontally really close, but not vertically, so move horizontally first
     if (Util.Random() < 0.5) {
       // Try moving left, then vertically, then right to endLocation
       backdoorWaypoints[1] = new MapLocation(Constants.BACKDOOR_WALL_BUFFER, currentLocation.y);
       // We need to know if endLocation is closer to the top wall or the bottom wall
       if (endLocation.y < mapHeight - endLocation.y) { // top wall
         backdoorWaypoints[2] =
             new MapLocation(Constants.BACKDOOR_WALL_BUFFER, Constants.BACKDOOR_WALL_BUFFER);
       } else { // bottom wall
         backdoorWaypoints[2] =
             new MapLocation(
                 Constants.BACKDOOR_WALL_BUFFER, mapHeight - 1 - Constants.BACKDOOR_WALL_BUFFER);
       }
     } else {
       // Try moving right, then vertically, then left to endLocation
       backdoorWaypoints[1] =
           new MapLocation(mapWidth - Constants.BACKDOOR_WALL_BUFFER, currentLocation.y);
       // We need to know if endLocation is closer to the top wall or the bottom wall
       if (endLocation.y < mapHeight - endLocation.y) { // top wall
         backdoorWaypoints[2] =
             new MapLocation(
                 mapWidth - 1 - Constants.BACKDOOR_WALL_BUFFER, Constants.BACKDOOR_WALL_BUFFER);
       } else { // bottom wall
         backdoorWaypoints[2] =
             new MapLocation(
                 mapWidth - 1 - Constants.BACKDOOR_WALL_BUFFER,
                 mapHeight - 1 - Constants.BACKDOOR_WALL_BUFFER);
       }
     }
   }
   // Upon calling getBackdoorWaypoint(), backdoorWaypointsIndex will be incremented by 1
   backdoorWaypointsIndex = -1;
   getBackdoorWaypoint();
 }