// @param allowGreaterDistance whether or not the robot is allowed to move further away in moving
  // toward
  public Direction moveToward(MapLocation location, Boolean allowGreaterDistance)
      throws GameActionException {

    if (location == null) return null;

    MapLocation currentLocation = this.robot.locationController.currentLocation();
    double currentDistance = currentLocation.distanceSquaredTo(location);

    Direction direction = this.robot.robotController.getLocation().directionTo(location);
    int directionInteger = directionToInt(direction);

    int[] offsets = {0, 1, -1, 2, -2};
    for (int offset : offsets) {

      direction = MovementController.directionFromInt(directionInteger + offset);
      MapLocation moveLocation = currentLocation.add(direction);
      if (!allowGreaterDistance && moveLocation.distanceSquaredTo(location) > currentDistance)
        continue;

      if (this.moveTo(direction)) {

        return direction;
      }
    }
    return null;
  }
  public Boolean canMoveSafely(
      Direction direction, Boolean moveAroundHQ, Boolean moveAroundTowers, Boolean moveAroundUnits)
      throws GameActionException {

    if (direction == null) return false;

    RobotController rc = this.robot.robotController;
    Boolean canMove = rc.canMove(direction);
    if (!canMove) return false;

    MapLocation currentLocation = this.robot.locationController.currentLocation();
    MapLocation moveLocation = currentLocation.add(direction);

    if (moveAroundHQ) {

      MapLocation[] towers = this.robot.unitController.enemyTowers();
      if (moveLocation.distanceSquaredTo(this.robot.locationController.enemyHQLocation())
          <= HQ.enemyAttackRadiusSquared(towers.length)) return false;
    }

    if (moveAroundTowers) {

      MapLocation[] towers = this.robot.unitController.enemyTowers();
      for (MapLocation tower : towers) {

        if (moveLocation.distanceSquaredTo(tower) <= Tower.type().attackRadiusSquared) return false;
      }
    }

    if (moveAroundUnits) {

      RobotInfo[] enemies = this.robot.unitController.nearbyEnemies();
      for (RobotInfo enemy : enemies) {

        if (!UnitController.isUnitTypeDangerous(enemy.type)) continue;
        if (moveLocation.distanceSquaredTo(enemy.location) <= enemy.type.attackRadiusSquared)
          return false;
      }
    }

    return true;
  }