/**
   * Finds max locations and lengths of rays in 8 directions
   *
   * @return
   */
  public void findRayPaths() {
    maxRangeLocs = new MapLocation[8];
    rayLengths = new int[8];

    for (int i = 0; i < 8; i++) { // find max range in each direction from pastr
      Direction dir = dirs[i];
      int rayLength = 1; // counts ray length
      MapLocation nextLoc = pLoc.add(dir);
      while (locationValid(nextLoc.add(dir))) { // while location is valid, expand ray
        rayLength++;
        nextLoc = nextLoc.add(dir);
      }
      maxRangeLocs[i] = nextLoc;
      rayLengths[i] = rayLength;
    }
  }
 /**
  * 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);
 }
 public MapLocation nextTarget() {
   if (currRayLength <= 3) { // switch to next direction
     dirIndex = (dirIndex + 1) % 8;
     currRayLength = rayLengths[dirIndex] - 1;
     lastTarget = maxRangeLocs[dirIndex];
     return lastTarget;
   } else { // reduce ray length in current direction
     lastTarget = lastTarget.add(dirs[dirIndex].opposite());
     currRayLength--;
     return lastTarget;
   }
 }
 /**
  * Checks if any of pastr squares are in tower range and updates pLoc to non-center pastr square
  * if necessary.
  *
  * @return true if in range, false else
  */
 public boolean pastrInRange() {
   if (pLoc.distanceSquaredTo(tLoc) <= attackRadius) {
     return true;
   }
   // check if other squares in pastr are in range
   MapLocation nextPLoc = pLoc.add(pLoc.directionTo(tLoc));
   while (nextPLoc.distanceSquaredTo(pLoc) <= pastrRadius) {
     if (nextPLoc.distanceSquaredTo(tLoc) <= attackRadius) {
       pLoc = nextPLoc;
       return true;
     }
   }
   return false;
 }