Exemple #1
0
  public static MapLocation spotOfTrollTower(RobotController rc, MapLocation pastr) {
    MapLocation target = pastr;
    int width = rc.getMapWidth();
    int height = rc.getMapHeight();
    int dist = 350;

    if (pastr.x < width / 2) {
      while (target.distanceSquaredTo(pastr) < dist && target.x > 0) {
        target = target.add(Direction.WEST);
      }
    } else {
      while (target.distanceSquaredTo(pastr) < dist && target.x < rc.getMapWidth() - 1) {
        target = target.add(Direction.EAST);
      }
    }
    if (pastr.y < height / 2) {
      while (target.distanceSquaredTo(pastr) < dist && target.y < height - 1) {
        target = target.add(Direction.SOUTH);
      }
    } else {
      while (target.distanceSquaredTo(pastr) < dist && target.y > 0) {
        target = target.add(Direction.NORTH);
      }
    }

    while (rc.senseTerrainTile(target) == TerrainTile.VOID && target.x < width / 2) {
      target = target.add(Direction.EAST);
    }
    while (rc.senseTerrainTile(target) == TerrainTile.VOID && target.x > width / 2) {
      target = target.add(Direction.WEST);
    }

    return target;
  }
Exemple #2
0
  public static MapLocation spotOfPastr(RobotController rc) {
    MapLocation target;
    int[] lookPlaces = {1, 1, 0, 3, 6, 7, 4, 5, 2, 3, 0, 2, 2, 3, 1, 4, 5, 3, 2, 5, 6};
    int counter = 0;
    Direction dir;
    int corner = findBestCorner(rc);
    rand = new Random();
    switch (corner) {
      case 1:
        target = new MapLocation(2, 2);
        break;
      case 2:
        target = new MapLocation(rc.getMapWidth() - 3, 2);
        break;
      case 3:
        target = new MapLocation(2, rc.getMapHeight() - 3);
        break;
      default:
        target = new MapLocation(rc.getMapWidth() - 3, rc.getMapHeight() - 3);
        break;
    }

    while (rc.senseTerrainTile(target).equals(TerrainTile.VOID)) {

      dir = directions[rand.nextInt(8)];
      target = target.add(dir);
      counter++;
    }
    return target;
  }
  public static void workOnCache(RobotController rc, int bytecodeLimit) {
    if (cacheFinished) return;

    int mapWidth = rc.getMapWidth();
    int mapHeight = rc.getMapHeight();

    int x, y;
    if (workStarted) {
      x = workLocX;
      y = workLocY;
    } else {
      x = mapWidth - 1;
      y = mapHeight - 1;
      workStarted = true;
    }

    outerloop:
    while (x >= 0) {
      while (y >= 0) {
        terrain[x][y] = rc.senseTerrainTile(new MapLocation(x, y));
        y--;
        // TODO: this is in a tight loop so it would be nice to do this check less often
        if (Clock.getBytecodeNum() > bytecodeLimit) break outerloop;
      }
      y = mapHeight - 1;
      x--;
    }

    workLocX = x;
    workLocY = y;

    if (x < 0) cacheFinished = true;
  }
Exemple #4
0
  public static MapLocation spotOfSensorTower(RobotController rc) {
    rand = new Random();
    MapLocation target = null;

    int corner = Utilities.findBestCorner(rc);

    switch (corner) {
      case 1:
        target = new MapLocation(5, 5);
        break;
      case 2:
        target = new MapLocation(rc.getMapWidth() - 6, 5);
        break;
      case 3:
        target = new MapLocation(5, rc.getMapHeight() - 6);
        break;
      default:
        target = new MapLocation(rc.getMapWidth() - 6, rc.getMapHeight() - 6);
        break;
    }

    Direction dir = directions[rand.nextInt(8)];
    // make sure we don't try to build on a void space
    while (rc.senseTerrainTile(target).equals(TerrainTile.VOID)) {
      target = target.add(dir);
      dir = directions[rand.nextInt(8)];
    }

    return target;
  }
 /**
  * Checks if square is void, out of map, out of tower range
  *
  * @param loc
  * @return
  */
 public boolean locationValid(MapLocation loc) {
   return !(rc.senseTerrainTile(loc) == TerrainTile.VOID
       || loc.x > xmax
       || loc.y > ymax
       || loc.x < 0
       || loc.y < 0
       || loc.distanceSquaredTo(tLoc) > attackRadius);
 }
Exemple #6
0
  // HQ or pastr calls this function to spend spare bytecodes computing paths for soldiers
  public static void work(MapLocation dest, int priority, int bytecodeLimit)
      throws GameActionException {
    int page = findFreePage(dest, priority);
    Debug.indicate("path", 1, "BFS Pathing to " + dest.toString() + "; using page " + page);
    if (page == -1) return; // We can't do any work, or don't have to

    if (!dest.equals(previousDest)) {
      Debug.indicate("path", 0, "BFS initingQueue");
      initQueue(dest);
    } else {
      Debug.indicate("path", 0, "BFS queue already inited");
    }

    previousDest = dest;
    previousRoundWorked = Clock.getRoundNum();
    previousPage = page;

    int mapWidth = rc.getMapWidth();
    int mapHeight = rc.getMapHeight();
    MapLocation enemyHQ = rc.senseEnemyHQLocation();
    boolean destInSpawn = dest.distanceSquaredTo(enemyHQ) <= 25;

    while (locQueueHead != locQueueTail && Clock.getBytecodeNum() < bytecodeLimit) {
      // pop a location from the queue
      MapLocation loc = locQueue[locQueueHead];
      locQueueHead++;

      int locX = loc.x;
      int locY = loc.y;
      for (int i = 8; i-- > 0; ) {
        int x = locX + dirsX[i];
        int y = locY + dirsY[i];
        if (x >= 0 && y >= 0 && x < mapWidth && y < mapHeight && !wasQueued[x][y]) {
          MapLocation newLoc = new MapLocation(x, y);
          if (rc.senseTerrainTile(newLoc) != TerrainTile.VOID
              && (destInSpawn || !Bot.isInTheirHQAttackRange(newLoc))) {
            publishResult(page, newLoc, dest, dirs[i]);

            // push newLoc onto queue
            locQueue[locQueueTail] = newLoc;
            locQueueTail++;
            wasQueued[x][y] = true;
          }
        }
      }
    }

    boolean finished = locQueueHead == locQueueTail;
    Debug.indicate("path", 2, "BFS finished = " + finished + "; locQueueHead = " + locQueueHead);
    writePageMetadata(page, Clock.getRoundNum(), dest, priority, finished);
  }
Exemple #7
0
 public static int countObstacles(int x, int y, RobotController rc) { // returns a 0 or a 1
   int terrainOrdinal =
       rc.senseTerrainTile(new MapLocation(x, y)).ordinal(); // 0 NORMAL, 1 ROAD, 2 VOID, 3 OFF_MAP
   switch (terrainOrdinal) {
     case 0:
       return NORMAL_COST;
     case 1:
       return ROAD_COST;
     case 2:
       return VOID_COST;
     case 3:
       return OFF_MAP_COST;
     default:
       return 0;
   }
 }
  /*
   * Moves towards the nearest enemy
   * Returns true if we moved or are in the right place
   */
  private static boolean doCloseWithEnemyMove(boolean ignoreThreat) {
    // Move to within attack range of the nearest enemy - ignore towers and HQ until later in the
    // game
    // We can move in closer if we are still out of range of the enemy
    RobotInfo nearest = null;
    RobotInfo preferred = null;
    RobotInfo[] enemies = rc.senseNearbyRobots(senseRange * 16, enemyTeam);
    boolean canFly = (myType == RobotType.DRONE);

    int now = Clock.getRoundNum();
    for (RobotInfo e : enemies) {
      // We want to find and circle units, not towers or HQ (until later in the game)
      if (now < maxRounds / 2 && (e.type == RobotType.HQ || e.type == RobotType.TOWER)) continue;
      // Drones on VOID tiles cannot be reached by ground troops - ignore them
      if (!canFly && rc.senseTerrainTile(e.location) != TerrainTile.NORMAL) continue;
      // Commanders are good at picking off miners, beavers and non combat buildings - have a
      // preference for them
      if (myType == RobotType.COMMANDER
          && commanderLikes(e.type)
          && (preferred == null
              || e.location.distanceSquaredTo(myLoc) < preferred.location.distanceSquaredTo(myLoc)))
        preferred = e;
      if (nearest == null
          || e.location.distanceSquaredTo(myLoc) < nearest.location.distanceSquaredTo(myLoc))
        nearest = e;
    }

    if (preferred != null) nearest = preferred;

    int attackRange = myType.attackRadiusSquared;
    if (myType == RobotType.LAUNCHER)
      attackRange = (1 + GameConstants.MISSILE_LIFESPAN) * (1 + GameConstants.MISSILE_LIFESPAN);

    if (nearest != null) {
      if (ignoreThreat || myLoc.distanceSquaredTo(nearest.location) > attackRange) {
        rc.setIndicatorString(2, "Closing with " + nearest.type + " at " + nearest.location);
        if (rc.isCoreReady()) tryMove(rc.getLocation().directionTo(nearest.location), ignoreThreat);
      } else {
        rc.setIndicatorString(
            2, "Holding at range with " + nearest.type + " at " + nearest.location);
      }
      return true;
    }
    return false;
  }
Exemple #9
0
  // finds best corner to collect milk where the return is an int as follows:
  // 1  2
  // 3  4
  public static int findBestCorner(RobotController rc) {
    double[][] pasture = rc.senseCowGrowth();

    double[] voids = new double[4];
    double[] cows = new double[4];
    double[] distances = new double[4];

    double max = 0;
    int corner = 0;
    double total = 0;
    MapLocation target = null;
    MapLocation current = rc.senseHQLocation();

    for (int k = 1; k <= 4; k++) {
      switch (k) {
        case 1:
          target = new MapLocation(5, 5);
          break;
        case 2:
          target = new MapLocation(rc.getMapWidth() - 6, 5);
          break;
        case 3:
          target = new MapLocation(5, rc.getMapHeight() - 6);
          break;
        default:
          target = new MapLocation(rc.getMapWidth() - 6, rc.getMapHeight() - 6);
          break;
      }

      while (target.x != current.x || target.y != current.y) {
        if (rc.senseTerrainTile(current) == TerrainTile.VOID) {
          total++;
        }
        current = current.add(current.directionTo(target));
      }

      voids[k - 1] = total;
      distances[k - 1] = rc.senseHQLocation().distanceSquaredTo(target);

      total = 0;
      current = rc.senseHQLocation();
    }

    // top left corner
    for (int k = 0; k < 10; k++) {
      for (int a = 0; a < 10; a++) {
        total += pasture[k][a];
      }
    }
    cows[0] = total;

    total = 0;

    // top right corner
    for (int k = rc.getMapWidth() - 11; k < rc.getMapWidth(); k++) {
      for (int a = 0; a < 10; a++) {
        total += pasture[k][a];
      }
    }
    cows[1] = total;

    total = 0;

    // bottom left corner
    for (int k = 0; k < 10; k++) {
      for (int a = rc.getMapHeight() - 11; a < rc.getMapHeight(); a++) {
        total += pasture[k][a];
      }
    }
    cows[2] = total;

    total = 0;

    // bottom right corner
    for (int k = rc.getMapWidth() - 11; k < rc.getMapWidth(); k++) {
      for (int a = rc.getMapHeight() - 11; a < rc.getMapHeight(); a++) {
        total += pasture[k][a];
      }
    }
    cows[3] = total;

    for (int k = 0; k < 4; k++) {
      total = cows[k] * 1 - voids[k] * 50 - distances[k] * .001;

      if (total > max) {
        max = total;
        corner = k + 1;
      }
    }

    return corner;
  }
Exemple #10
0
  // this method will advance one square towards a target and try to avoid enemies as much as
  // possible
  public static void avoidEnemiesMove(RobotController rc, MapLocation target) {
    try {
      // first we will find all enemy bots near us
      GameObject[] nearByBots = rc.senseNearbyGameObjects(Robot.class, 15, rc.getTeam().opponent());
      Direction direction = rc.getLocation().directionTo(target);

      // if we don't see anything then lets head towards target
      if (nearByBots.length == 0) {
        // rc.setIndicatorString(2, "No enemies detected");
        // rc.setIndicatorString(1, "x: "+target.x + " y: " + target.y);
        direction = rc.getLocation().directionTo(target);
        if (rc.canMove(direction)) // &&
        // !rc.senseTerrainTile(rc.getLocation().add(direction).add(direction)).equals(TerrainTile.VOID))
        {
          if (rc.isActive()) {
            rc.move(direction);
          }
        } else {
          MapLocation target2 = rc.getLocation().add(direction);
          if (rc.senseTerrainTile(target2).equals(TerrainTile.VOID)) {
            int j = 0;
            while (rc.senseTerrainTile(target2).equals(TerrainTile.VOID)) {
              rc.setIndicatorString(0, "" + j);
              j++;

              target2 = target2.add(direction);
            }
            Utilities.MoveMapLocation(rc, target2, false);
          }
          /*
          int distanceRight = 0;
          int distanceLeft = 0;
             direction = direction.rotateRight();
             while (!rc.canMove(direction) && rc.senseTerrainTile(rc.getLocation().add(direction)).equals(TerrainTile.VOID))
             {
                 direction = direction.rotateRight();
             }
             if (rc.isActive())
             {
                 if (rc.canMove(direction))
                 {
                     rc.move(direction);
                 }
             }
             */
        }
      }
      // otherwise we need to avoid them
      else {
        rc.setIndicatorString(2, "Avoiding enemies");
        rc.setIndicatorString(1, "Numb of Enemies: " + nearByBots.length);
        // now we will calculate the distance form all 5 spots towards are target and the distance
        // from that spot to all enemies we can see
        // we will pick the one with the greatest distance
        int[] distancesToLocations = new int[5];

        for (int k = 0; k < distancesToLocations.length; k++) {
          distancesToLocations[k] = 0;
        }
        MapLocation spot;
        Direction newDir;

        // first we look 90 to our right
        newDir = direction.rotateRight().rotateRight();
        for (int j = 0; j < 5; j++) {
          if (rc.canMove(newDir)) {
            spot = rc.getLocation().add(newDir);
            for (int i = 0; i < nearByBots.length; i++) {
              // System.out.println("entering for loop");
              distancesToLocations[j] += spot.distanceSquaredTo(rc.senseLocationOf(nearByBots[i]));
            }
          } else {
            distancesToLocations[j] = -123;
          }
          // every time through the loop we look one further to the left
          newDir.rotateLeft();
        }

        int indexOfLargest = 0;
        int largest = distancesToLocations[0];
        for (int j = 1; j < distancesToLocations.length; j++) {
          if (largest < distancesToLocations[j]) {
            indexOfLargest = j;
            largest = distancesToLocations[j];
          }
        }

        // now we orientate newDir to the right spot
        newDir = direction.rotateRight().rotateRight();
        for (int i = 0; i <= indexOfLargest; i++) {
          newDir = newDir.rotateLeft();
        }

        while (!rc.isActive()) {
          rc.yield();
        }

        // now we can finally move
        if (rc.isActive()) {
          if (rc.canMove(newDir)) {
            rc.move(newDir);
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
Exemple #11
0
  public static void MoveMapLocation(RobotController rc, MapLocation target, boolean sneak) {
    MapLocation[] pastLocations = new MapLocation[10];
    int side = 45;
    Direction dir;
    Direction newDir;
    rand = new Random();
    // we initialize pastLocations to hold our current location 5 times
    for (int i = 0; i < pastLocations.length; i++) {
      pastLocations[i] = rc.getLocation();
    }

    // this method will run until we get to our target location
    while (!rc.getLocation().equals(target)) {
      // we put the try block inside of the while loop so an exception won't terminate the method
      try {
        dir = rc.getLocation().directionTo(target);
        newDir = Direction.NONE;

        // simple shoot at an enemy if we see one will need to be improved later
        Robot[] nearbyEnemies = rc.senseNearbyGameObjects(Robot.class, 10, rc.getTeam().opponent());
        if (nearbyEnemies.length > 0 && rc.senseRobotInfo((Robot) nearbyEnemies[0]).health < 201) {
          fire(rc);
        }
        // if we can move towards target and we haven't been on the square recently then lets move
        else if (rc.canMove(dir)
            && !MapLocationInArray(rc, rc.getLocation().add(dir), pastLocations)) {
          newDir = dir;
          // if we found a direction to move then we go to it
          if (newDir != Direction.NONE) {
            // now we decide if we are going to sneak or run
            if (sneak) {
              // another check to make sure we don't throw any exceptions
              if (rc.isActive() && rc.canMove(newDir)) {
                // System.out.println(newDir);
                rc.sneak(newDir);
              }
            } else {
              // another check to make sure we don't throw any exceptions
              if (rc.isActive() && rc.canMove(newDir)) {
                rc.move(newDir);
              }
            }
          }
          side = 45;
        } else {
          // if their is a robot blocking our way then we just move in a random direction
          if (rc.senseObjectAtLocation(rc.getLocation().add(dir)) != null) {
            // newDir = directions[rand.nextInt(8)];
            MoveDirection(rc, dir, sneak);
          } else {
            // rc.setIndicatorString(2, "Looking elswhere");
            Direction dir2 = dir;
            MapLocation right;
            MapLocation left;
            dir2 = (dir.rotateRight());
            while (!rc.canMove(dir2)) {
              dir2 = dir2.rotateRight();
            }
            right = rc.getLocation().add(dir2);

            dir2 = dir.rotateLeft();
            while (!rc.canMove(dir2)) {
              dir2 = dir2.rotateLeft();
            }

            left = rc.getLocation().add(dir2);

            // left seems better so lets go that way
            if (left.distanceSquaredTo(target) < right.distanceSquaredTo(target)) {
              side = 1;
            }
            // right seems better so lets try that way
            else {
              side = 0;
            }

            // we will go hugging one side of obstacle until we get back on our original line
            while (!dir2.equals(dir) && !rc.getLocation().equals(target)) // && rc.canMove(dir2))
            {
              try {
                if (rc.isActive()) {
                  // rc.setIndicatorString(1, "Trying to Avoid");
                  // rc.setIndicatorString(2, ""+side);
                  dir2 = rc.getLocation().directionTo(target);
                  if (rc.canMove(dir2)
                      && !MapLocationInArray(rc, rc.getLocation().add(dir2), pastLocations)) //  &&
                  // !rc.senseTerrainTile(rc.getLocation().add(dir2).add(dir2)).equals(TerrainTile.VOID))
                  {
                    // rc.setIndicatorString(0, "Going straight");
                  } else {
                    for (int i = 0; i < 4; i++) {
                      if (side == 1) {
                        dir2 = dir2.rotateLeft();
                      } else {
                        dir2 = dir2.rotateRight();
                      }
                      if (rc.senseTerrainTile(rc.getLocation().add(dir2))
                          .equals(TerrainTile.OFF_MAP)) {
                        dir2 = Direction.NONE;
                        i = 48;
                      } else if ((rc.canMove(dir2)
                          || (rc.senseObjectAtLocation(rc.getLocation().add(dir2))
                              != null))) // && !MapLocationInArray(rc, rc.getLocation().add(dir2),
                      // pastLocations))// &&
                      // !rc.senseTerrainTile(rc.getLocation().add(dir2).add(dir2)).equals(TerrainTile.VOID))
                      {
                        i = 48;
                      } else if (i == 3) {
                        dir2 = Direction.NONE;
                        // rc.setIndicatorString(1, "We failed to find a spot");
                      }
                    }
                  }

                  // if we can move
                  if (dir2 != Direction.NONE) {
                    if (rc.isActive()) {
                      if (rc.canMove(dir2)) {
                        if (sneak) {
                          rc.sneak(dir2);
                        } else {
                          rc.move(dir2);
                        }
                      } else {
                        MoveDirection(rc, dir2, sneak);
                      }
                    }
                  } else {
                    if (side == 1) {
                      side = 0;
                    } else {
                      side = 1;
                    }
                  }
                }
                // rc.setIndicatorString(0, "Dir: "+ dir +" Dir2: " + dir2);
              } catch (Exception e) {
                // tell the console we through an exception in utility object for debug purposes
                // System.out.println("Utility Exception");
                // System.out.println(e.toString());
                e.printStackTrace();
                rc.yield();
              }
              if (!rc.getLocation().equals(pastLocations[(pastLocations.length - 1)])) {
                for (int j = 0; j < (pastLocations.length - 1); j++) {
                  pastLocations[j] = pastLocations[j + 1];
                  // System.out.println(pastLocations[j]);
                }
                // stick current local into array
                pastLocations[(pastLocations.length - 1)] = rc.getLocation();
              }

              rc.yield();
            }
            // rc.setIndicatorString(1, "Not trying to Avoid");
          }
        }

        // now we  shift everything up one in pastLocations
        if (rc.getLocation() != pastLocations[(pastLocations.length - 1)]) {
          for (int j = 0; j < (pastLocations.length - 1); j++) {
            pastLocations[j] = pastLocations[j + 1];
            // System.out.println(pastLocations[j]);
          }
          // stick current local into array
          pastLocations[(pastLocations.length - 1)] = rc.getLocation();
        }

        rc.yield();
      } catch (Exception e) {
        // tell the console we through an exception in utility object for debug purposes
        System.out.println("Utility Exception");
        e.printStackTrace();
        // System.out.println(e.toString());
        rc.yield();
      }
    }
  }
  public static void computeAndPublish(MapLocation here, MapLocation pastr, RobotController rc)
      throws GameActionException {
    // Useful data
    int attackRange =
        (int)
            (Math.sqrt(RobotType.NOISETOWER.attackRadiusMaxSquared)
                - 3); // -3 becauase we actually have to shoot past the square
    int attackRangeSq = attackRange * attackRange;
    int mapWidth = rc.getMapWidth();
    int mapHeight = rc.getMapHeight();
    Direction[] dirs =
        new Direction[] {
          Direction.NORTH_WEST,
          Direction.SOUTH_WEST,
          Direction.SOUTH_EAST,
          Direction.NORTH_EAST,
          Direction.NORTH,
          Direction.WEST,
          Direction.SOUTH,
          Direction.EAST
        };
    int[] dirsX = new int[] {1, 1, -1, -1, 0, 1, 0, -1};
    int[] dirsY = new int[] {1, -1, -1, 1, 1, 0, -1, 0};

    // Set up the queue
    MapLocation[] locQueue =
        new MapLocation
            [(2 * RobotType.NOISETOWER.attackRadiusMaxSquared + 1)
                * (2 * RobotType.NOISETOWER.attackRadiusMaxSquared + 1)];
    int locQueueHead = 0;
    int locQueueTail = 0;
    boolean[][] wasQueued = new boolean[GameConstants.MAP_MAX_WIDTH][GameConstants.MAP_MAX_HEIGHT];

    // Push pastr onto queue
    locQueue[locQueueTail] = pastr;
    locQueueTail++;
    wasQueued[pastr.x][pastr.y] = true;

    while (locQueueHead != locQueueTail) {
      // pop a location from the queue
      MapLocation loc = locQueue[locQueueHead];
      locQueueHead++;

      int locX = loc.x;
      int locY = loc.y;
      for (int i = 8; i-- > 0; ) {
        int x = locX + dirsX[i];
        int y = locY + dirsY[i];
        if (x > 0 && y > 0 && x < mapWidth && y < mapHeight && !wasQueued[x][y]) {
          MapLocation newLoc = new MapLocation(x, y);
          if (here.distanceSquaredTo(newLoc) <= attackRangeSq) {
            if (rc.senseTerrainTile(newLoc) != TerrainTile.VOID) {
              writeHerdDir(newLoc, dirs[i], rc);

              // push newLoc onto queue
              locQueue[locQueueTail] = newLoc;
              locQueueTail++;
              wasQueued[x][y] = true;
            }
          }
        }
      }
    }
  }
  // Checks to see if building here would block movement
  static boolean wouldBlock(Direction d) {
    MapLocation target = myLoc.add(d);
    if ((target.x + target.y) % 2
        != (myHQ.x + myHQ.y)
            % 2) // A quick check to ensure we are lined up with the HQ - this will create a
                 // chequerboard pattern
    return true;

    RobotInfo[] units = rc.senseNearbyRobots(2, myTeam);
    boolean hasTop = false;
    boolean hasBottom = false;
    boolean hasLeft = false;
    boolean hasRight = false;
    boolean[] blocked = new boolean[8]; // The 8 locations around us
    int clearTiles = 8;
    MapLocation test = rc.getLocation().add(d);

    test = test.add(Direction.NORTH_WEST);
    if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) {
      hasTop = true;
      hasLeft = true;
    } else {
      blocked[0] = true;
      clearTiles--;
    }
    test = test.add(Direction.EAST);
    if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) {
      hasTop = true;
    } else {
      blocked[1] = true;
      clearTiles--;
    }
    test = test.add(Direction.EAST);
    if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) {
      hasTop = true;
      hasRight = true;
    } else {
      blocked[2] = true;
      clearTiles--;
    }
    test = test.add(Direction.SOUTH);
    if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) {
      hasRight = true;
    } else {
      blocked[3] = true;
      clearTiles--;
    }
    test = test.add(Direction.SOUTH);
    if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) {
      hasRight = true;
      hasBottom = true;
    } else {
      blocked[4] = true;
      clearTiles--;
    }
    test = test.add(Direction.WEST);
    if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) {
      hasBottom = true;
    } else {
      blocked[5] = true;
      clearTiles--;
    }
    test = test.add(Direction.WEST);
    if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) {
      hasBottom = true;
      hasLeft = true;
    } else {
      blocked[6] = true;
      clearTiles--;
    }
    test = test.add(Direction.NORTH);
    if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) {
      hasLeft = true;
    } else {
      blocked[7] = true;
      clearTiles--;
    }

    // Check for a line down the middle
    if (blocked[1] && blocked[5] && hasLeft && hasRight) return true;
    // Check for line across
    if (blocked[3] && blocked[7] && hasTop && hasBottom) return true;
    // Check for blocked corners
    if (clearTiles > 2) {
      if (!blocked[0] && blocked[1] && blocked[7]) return true;
      if (!blocked[2] && blocked[1] && blocked[3]) return true;
      if (!blocked[4] && blocked[3] && blocked[5]) return true;
      if (!blocked[6] && blocked[5] && blocked[7]) return true;
    }
    // System.out.println("wouldBlock = false, blocked="+blocked+" hasLeft = "+hasLeft+"
    // hasRight="+hasRight+" hasTop="+hasTop+" hasBootom="+hasBottom);
    return false;
  }