// method runs when robot is in a dead end and has to back up and go around
  public static void turnAround(boolean r, MapSystem ms, Movement mv) {
    mv.turn(ms); // 180 degree turn
    movRow(); // move forward

    // check for empty adjacent space
    boolean[] scanResults = new boolean[3];
    scanResults = mapObj.scanAll();
    // Move to said empty space
    if (scanResults[0] && !scanResults[2]) { // Obstacle on the Left
      mv.turn(scanResults[0], ms); // turn right
      movRow();
    } else { // Obstacle on the Right
      mv.turn(!scanResults[2], ms); // turn left
      movRow();
      mv.turn(!scanResults[2], ms);
      movRow();
      // move forward 2 cells, scanning as we go
      // if an obstacle is still on the same axis as the first
      //    class it as a different obstacle
      //    move forward a cell
      //    scan again - recursive
      // move back to the correct column

      // if at a 'limit cell', turn left instead of right

    }
  }
  /** Turns the movement angle from the startAngle to the endAngle with the specified speed. */
  protected void turnTo(Movement movement, float startAngle, float endAngle, float speed) {
    startAngle = ensureAngleWithinBounds(startAngle);
    endAngle = ensureAngleWithinBounds(endAngle);
    if (startAngle == endAngle) {
      movement.set(0, 0);
    } else {

      float distanceLeft;
      float distanceRight;
      float pi2 = (float) (2 * Math.PI);

      if (startAngle < endAngle) {
        distanceLeft = startAngle - endAngle + pi2;
        distanceRight = endAngle - startAngle;
      } else {
        distanceLeft = startAngle - endAngle;
        distanceRight = endAngle - startAngle + pi2;
      }

      if (distanceLeft < distanceRight) {
        speed = -Math.abs(speed);
        movement.set(speed, (long) (distanceLeft / -speed));
      } else {
        speed = Math.abs(speed);
        movement.set(speed, (long) (distanceRight / speed));
      }
    }
  }
 /** Stops this Transform3D. Any moving velocities are set to zero. */
 public void stop() {
   velocity.setTo(0, 0, 0);
   velocityMovement.set(0, 0);
   velocityAngleX.set(0, 0);
   velocityAngleY.set(0, 0);
   velocityAngleZ.set(0, 0);
 }
Example #4
0
 private void tfrReset() {
   mOrigin.update(
       mGpsParams,
       mScale,
       mPan,
       mMovement.getLongitudePerPixel(),
       mMovement.getLatitudePerPixel(),
       getWidth(),
       getHeight());
 }
 /**
  * Sets the velocity. The velocity is automatically set to zero after the specified amount of time
  * has elapsed. If the specified time is FOREVER, then the velocity is never automatically set to
  * zero.
  */
 public void setVelocity(Vector3D v, long time) {
   if (velocity != v) {
     velocity.setTo(v);
   }
   if (v.x == 0 && v.y == 0 && v.z == 0) {
     velocityMovement.set(0, 0);
   } else {
     velocityMovement.set(1, time);
   }
 }
Example #6
0
  @Override
  public Movement getMovement() {

    // this will create a movement call
    Movement movement = new Movement(0, 0, 0);

    // this will change the movement call based on the state
    switch (_state) {
      case Start:

        // this will change the state to the drive forward state
        changeState(AutoState.DriveForward);

        break;

      case DriveForward:
        if (getTimeFromStateChange() > seconds(2)) {

          // this will change the state to the stopped state if 2 seconds have passed
          changeState(AutoState.Spin);

        } else {

          // this will set the movement call's linear speed to 0.5
          movement.setLinearSpeed(0.5f);
        }

        break;

      case Spin:
        if (getTimeFromStateChange() > seconds(5)) {

          // this will change the state to the stopped state if 5 seconds have passed
          changeState(AutoState.Stop);

        } else {

          // this will set the movement call's spin speed to 0.5
          movement.setSpinSpeed(0.5f);
        }

        break;

      case Stop:

        // this will do nothing

        break;
    }

    // this will return the movement call
    return movement;
  }
Example #7
0
  /** @param canvas */
  private void drawTiles(Canvas canvas) {
    mPaint.setShadowLayer(0, 0, 0, 0);

    if (null != mTiles) {

      for (int tilen = 0; tilen < mTiles.getTilesNum(); tilen++) {

        BitmapHolder tile = mTiles.getTile(tilen);

        /*
         * Scale, then move under the plane which is at center
         */
        boolean nochart = false;
        if (null == tile) {
          nochart = true;
        } else if (null == tile.getBitmap()) {
          nochart = true;
        }
        if (nochart) {
          continue;
        }

        /*
         * Pretty straightforward. Pan and draw individual tiles.
         */
        tile.getTransform().setScale(mScale.getScaleFactor(), mScale.getScaleCorrected());
        tile.getTransform()
            .postTranslate(
                getWidth() / 2.f
                    - BitmapHolder.WIDTH / 2.f * mScale.getScaleFactor()
                    + ((tilen % mTiles.getXTilesNum()) * BitmapHolder.WIDTH
                            - BitmapHolder.WIDTH * (int) (mTiles.getXTilesNum() / 2))
                        * mScale.getScaleFactor()
                    + mPan.getMoveX() * mScale.getScaleFactor()
                    + mPan.getTileMoveX() * BitmapHolder.WIDTH * mScale.getScaleFactor()
                    - (float) mMovement.getOffsetLongitude() * mScale.getScaleFactor(),
                getHeight() / 2.f
                    - BitmapHolder.HEIGHT / 2.f * mScale.getScaleCorrected()
                    + mPan.getMoveY() * mScale.getScaleCorrected()
                    + ((tilen / mTiles.getXTilesNum()) * BitmapHolder.HEIGHT
                            - BitmapHolder.HEIGHT * (int) (mTiles.getYTilesNum() / 2))
                        * mScale.getScaleCorrected()
                    + mPan.getTileMoveY() * BitmapHolder.HEIGHT * mScale.getScaleCorrected()
                    - (float) mMovement.getOffsetLatitude() * mScale.getScaleCorrected());

        Bitmap b = tile.getBitmap();
        if (null != b) {
          canvas.drawBitmap(b, tile.getTransform(), mPaint);
        }
      }
    }
  }
  /**
   * Updates this Transform3D based on the specified elapsed time. The location and angles are
   * updated.
   */
  public void update(long elapsedTime) {
    float delta = velocityMovement.getDistance(elapsedTime);
    if (delta != 0) {
      temp.setTo(velocity);
      temp.multiply(delta);
      location.add(temp);
    }

    rotateAngle(
        velocityAngleX.getDistance(elapsedTime),
        velocityAngleY.getDistance(elapsedTime),
        velocityAngleZ.getDistance(elapsedTime));
  }
Example #9
0
  public boolean equals(Object m) {
    if (m == null) return false;

    Movement mov = (Movement) m;

    if (this.sourceSquare != mov.sourceSquare) return false;
    if (this.destinationSquare != mov.destinationSquare) return false;

    if (this.getPromotionGenericPiece() != mov.getPromotionGenericPiece()) {
      return false;
    }

    return true;
  }
Example #10
0
  public void run() {
    motor_left.resetTachoCount();
    motor_left.regulateSpeed(true);
    Movement.motor_left.smoothAcceleration(true);
    int previousCommandCount = -1;

    while (true) {
      if (Movement.getCommandCount() == previousCommandCount) {
        try {
          Thread.sleep(10);
        } catch (InterruptedException e) {
        }
        continue;
      }

      previousCommandCount = Movement.getCommandCount();
      setToAngle(ControlCentre.getTargetSteeringAngleLeft());
      int new_angle = getToAngle();
      if (new_angle < 10) LCD.drawString("  ", 8, 1);
      else if (new_angle < 100) LCD.drawString(" ", 9, 1);
      LCD.drawString(Integer.toString(new_angle), 7, 1);
      LCD.drawString("R", 11, 1);

      int cur_angle = getCurrentSteeringAngle();
      double delta = new_angle - cur_angle;
      final double C = Movement.rotConstant;
      double turn_angle = 0;

      if (Math.abs(delta) < thresholdAngle / 2.0) {
        continue;
      } else if (Math.abs(delta) >= thresholdAngle / 2.0 && Math.abs(delta) < thresholdAngle) {
        delta = thresholdAngle * delta / Math.abs(delta);
      }
      setCurrentSteeringAngle((int) (cur_angle + delta) % 360);

      if (delta != 0 && Math.abs(delta) < 180) {
        turn_angle = C * delta;
      } else if (delta >= 180 && delta < 360) {
        turn_angle = -C * (360 - delta);
      } else if (delta <= -180) {
        turn_angle = C * (360 + delta);
      } else {
          /* No turning needed */
        continue;
      }

      motor_left.rotate((int) Math.round(turn_angle));
    }
  }
  private static void archonMicro(RobotController rc, RobotInfo enemyArchon)
      throws GameActionException {
    if (rc.isCoreReady()) {
      int dist = myLoc.distanceSquaredTo(enemyArchon.location);
      // When not adjacent to the archon, walk/mine through to him.
      if (dist > 2) {
        Direction desired = myLoc.directionTo(enemyArchon.location);
        Direction dir = Movement.getBestMoveableDirection(desired, rc, 2);
        if (dir != Direction.NONE) {
          rc.move(dir);
        } else if (shouldMine(rc, desired)) {
          rc.clearRubble(desired);
        } else if (shouldMine(rc, desired.rotateLeft())) {
          rc.clearRubble(desired.rotateLeft());
        } else if (shouldMine(rc, desired.rotateRight())) {
          rc.clearRubble(desired.rotateRight());
        }
      }
      // When adjacent to archon, rotate to the left/right when possible.
      else {
        Direction dir = myLoc.directionTo(enemyArchon.location);
        if (rc.canMove(dir.rotateLeft())) {
          rc.move(dir.rotateLeft());
        } else if (rc.canMove(dir.rotateRight())) {
          rc.move(dir.rotateRight());
        }
      }
    }

    if (rc.isWeaponReady()) {
      if (rc.canAttackLocation(enemyArchon.location)) {
        rc.attackLocation(enemyArchon.location);
      }
    }
  }
  // Method scans input and maps it; if obstacle is in front, left and right,
  // backpedal.  If there is a space adjacent but an obstacle at the front,
  // turns to move around the obstacle using the available space.
  public static void movRow() {
    double nextCell = mapObj.basicProb(); // work out probability
    // output to RConsole through BlueTooth
    // btObj.stringToRCon("Object Probability in next Cell: %2f" + nextCell);

    // mapObj.printMap(columns, numOfRowCells);

    // sonar scan around of the robot
    boolean[] scanResults = new boolean[3];
    scanResults = mapObj.scanAll();
    mapObj.updateMap(scanResults);
    // btObj.stringToRCon("Scan Results: " + scanResults[0] + ", " + scanResults[1] + ", " +
    // scanResults[2]);
    // mapObj.printMap(columns, numOfRowCells);

    if (scanResults[1]) { // if there's an obstacle in front
      // if there's an obstacle to the left & right.  i.e. a dead end
      if (scanResults[0] && scanResults[2]) {
        turnAround(scanResults[2], mapObj, movObj); // move backwards
      } else {
        // call movAround() method to navigate around the obstacle
        movAround(scanResults[1], mapObj, movObj);
      }
    } else {
      movObj.nextCell(mapObj); // move forward a cell
    }
  }
Example #13
0
  // enter a world map square
  //  - if there is a portal to a special location then use it
  //  - else create the appropraite outdoor area map
  //
  public static void exitWorldMap(Map m, int tx, int ty) {
    Thing h = Game.hero();

    // record movement time
    Time.logTime(Movement.moveCost(m, h, tx, ty));

    Thing p = m.getFlaggedObject(tx, ty, "IsPortal");
    if (p != null) {
      Portal.travel(p, h);
    } else {
      // put hero into a local area map
      Map nm = WorldMap.createArea(m, tx, ty);

      // phantom Portal
      p = Portal.create();
      Thing t = nm.getEntrance();
      Portal.setDestination(p, nm, t.x, t.y);

      // could build a portal here so we can return to exact location map
      // Don't think we really want this though
      //   addThing(p,tx,ty);

      Portal.travel(p, h);
    }
  }
Example #14
0
  /** The background process */
  @Override
  public void run() {

    boolean playerHasChanged;

    do {
      Movement machineMovement = machinePlays();
      if (machineMovement != null) {
        playerHasChanged =
            doMovement(GameLogic.PLAYER_TWO, machineMovement.getColumn(), machineMovement.getRow());
      } else {
        // if machine movement is null.. machine cannot play
        playerHasChanged = true;
      }
      // it can happen that the human can not play...
    } while (!playerHasChanged);
  }
  // Method to move around an obstacle - runs when obstacle is in front
  public static void movAround(boolean r, MapSystem ms, Movement mv) {
    mv.turn(r, ms); // true = right turn; false = left turn
    movRow(); // scan and move forward if necessary
    mv.turn(!r, ms); // invert the boolean to turn the other way

    // move forward twice to pass the obstacle
    movRow();
    ++loop2;
    movRow();
    ++loop2;

    mv.turn(!r, ms); // turn to face original column
    boolean extend = mapObj.scanAhead(); // flag to check object is passed
    while (extend) {
      mv.turn(r, ms); // turn to move along the axis
      movObj.nextCell(mapObj);
      ++loop2;
      mv.turn(!r, ms); // face the original column
      if (!mapObj.scanAhead()) { // if an obstacle is not found anymore
        extend = false; // break the while loop
      } else {
      }
    }
    movRow(); // move into the original column
    mv.turn(r, ms); // face the correct way to continue the patrol
  }
Example #16
0
  @Override
  public void doSearch() {
    ArrayList<Node> list = new ArrayList<>(); // nos visitados
    Stack<Node> stack = new Stack<>();
    Node root = gameTree.getRoot();
    stack.push(root);
    while (!stack.empty()) {
      System.out.println("Pilha:-------------------------");
      Iterator<Node> it2 = stack.iterator();
      while (it2.hasNext()) {
        it2.next().getBoard().print();
      }
      System.out.println("---------------------------:");
      Node t = stack.pop();
      list.add(t);
      if (Movement.getPins(t) == 1) {
        System.out.println("SOLUCAO ENCONTRADA.");
        Iterator<Node> it = list.iterator();
        while (it.hasNext()) {
          it.next().getBoard().print();
        }
        return;
      }

      ArrayList<Node> mov = Movement.getMovements(t);
      System.out.println("Opcoes de movimento: " + mov.size());
      if (mov.isEmpty() && stack.empty()) { // sem movimentos possiveis
        break;
      }

      // Existem movimentos entao empilha e comeca de novo
      for (Node node : mov) {
        System.out.println("Numero de pins: " + Movement.getPins(node));
        stack.push(node);
      }
    }
    System.out.println("SOLUCAO NAO ENCONTRADA!");
    //        Iterator<Node> it = list.iterator();
    //        while(it.hasNext()) {
    //            it.next().getBoard().print();
    //        }
  }
Example #17
0
  public void run() {
    while (true) {
      try {
        Robot[] enemies = rc.senseNearbyGameObjects(Robot.class, 35, rc.getTeam().opponent());

        if (rc.isActive()) {
          Movement.fire(rc, enemies, null);
          HQFunctions.SpawnSoldiers(rc);
        }

        if (Clock.getRoundNum() % 50 == 0) {
          System.out.println();
          System.out.println("Enemy Bots: ");
          int[] AllEnemies = FightMicro.AllEnemyBots(rc);
          for (int i = 0; i < AllEnemies.length; i++) {
            System.out.print(FightMicro.getBotLocation(AllEnemies[i]));
          }
          System.out.println();
        }

        int broadcast = rc.readBroadcast(rallyPoint2);
        if (broadcast != 0) {
          if (broadcast != fightZone) {
            fightZone = broadcast;
            roundSet = Clock.getRoundNum();
          }
          // now it is time for us to move on
          else if (roundSet + 75 < Clock.getRoundNum()) {
            fightZone = 0;
            rc.broadcast(rallyPoint2, 0);
          }
        }

        if (Clock.getRoundNum() % 5 == 0 && Clock.getRoundNum() > 100) {
          // HQFunctions.moveTargetLocationRandomly(rc);
          /*
          if (goneForPastr && (rc.sensePastrLocations(rc.getTeam()).length > 0 || roundNum > (Clock.getRoundNum() - 250)))
          {
              HQFunctions.setTargetLocation(rc, goneForPastr);
          }
          else
          {
              goneForPastr = HQFunctions.setTargetLocation(rc, goneForPastr);
              roundNum = Clock.getRoundNum();
          }*/
          HQFunctions.setTargetLocation(rc, true);
          // HQFunctions.findInitialRally(rc);

        }
      } catch (Exception e) {
      }
      rc.yield();
    }
  }
Example #18
0
 private void loadPrefs() {
   // Restore preferences
   SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
   putUrl = settings.getString("REMOTE_EYES_PUT_URL", "http://example.com:8080/cellserv");
   noise.setOffsetPulsePercent(settings.getInt("servo1Percent", 50), 0);
   noise.setOffsetPulsePercent(settings.getInt("servo2Percent", 50), 1);
   noise.setOffsetPulsePercent(settings.getInt("servo3Percent", 50), 2);
   noise.setOffsetPulsePercent(settings.getInt("servo4Percent", 50), 3);
   mover.setOffset(settings.getInt("wheelOffset", 0));
   RobotStateHandler.ROBOT_ID = settings.getString("ROBOT_ID", RobotStateHandler.ROBOT_ID);
 }
Example #19
0
  protected void useMovement(Unit U) {
    // if movement forward is possible, move forward 1 square
    // otherwise, rotate left or right

    movementPoints = Movement.getMovement(map, U);

    if (movementPoints[1].length == 0) {
      randomRotate(U);
    } else {
      U.setXYCoordinate(movementPoints[1][0], map);
      U.usePoints(U.getMovementCost());
    }
  }
Example #20
0
 public void run() {
   while (true) {
     try {
       if (rc.isActive()) {
         if (rc.getLocation().equals(towerSpot)
             || (rc.getLocation().isAdjacentTo(towerSpot)
                 && !rc.canMove(rc.getLocation().directionTo(towerSpot)))) {
           rc.construct(RobotType.NOISETOWER);
         } else {
           Movement.MoveMapLocation(rc, towerSpot, false);
         }
       }
     } catch (Exception e) {
     }
   }
 }
Example #21
0
  public static Movement getMovementEnroqueCorto(Colour turno) {
    Movement mov = new Movement();

    if (turno == Colour.WHITE) {
      mov.setSourcePiece(Piece.WHITE_KING);
      mov.setSource(Square.e1);
      mov.setDestination(Square.g1);
    } else {
      mov.setSourcePiece(Piece.BLACK_KING);
      mov.setSource(Square.e8);
      mov.setDestination(Square.g8);
    }

    return mov;
  }
Example #22
0
 private static void collectMessage() throws InterruptedException {
   boolean atend = false;
   int N = 0;
   while (atend == false) {
     N = N + 1; // % 100;
     Movement.setCommandCount(N);
     LCD.drawString("Recv:" + Integer.toString(N), 2, 2);
     try {
       // Bluetooth.getConnectionStatus();
       int message = inputStream.readInt();
       LCD.drawString("Rcvd:" + Integer.toString(N), 2, 3);
       if (message >= (1 << 26)) {
         LCD.drawString("end" + Integer.toString(N), 12, 2);
         atend = true;
         // Thread atendDisplay = new ScreenWriter(Integer.toString(message),7);
         LCD.drawString(Integer.toString(message), 0, 7);
         // atendDisplay.start();
         // System.exit();
         LCD.drawString("stopped" + message, 0, 2);
       } else if (message < (1 << 26)) {
         // Thread newMessageDisplay = new ScreenWriter(Integer.toString(message),6);
         // LCD.drawString("display"+Integer.toString(N), 6, 0);
         // newMessageDisplay.start();
         LCD.drawString("        ", 5, 6);
         LCD.drawString("Msg:" + Integer.toString(message), 0, 6);
         // LCD.drawString("decode:"+Integer.toString(N), 6, 1);
         parseMessage(message);
         // LCD.drawString("decoded:"+Integer.toString(N), 6, 0);
       }
       // inputStream.close();
       // inputStream = connection.openDataInputStream();
     } catch (IOException e) {
       Thread errorConnection = new ScreenWriter("Error - connect back up", 7);
       errorConnection.start();
       // connection = Bluetooth.waitForConnection();
       Thread connectedDisplay = new ScreenWriter("Connection Opened", 7);
       connectedDisplay.start();
     }
   }
 }
Example #23
0
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ServoOn");
    // wl.acquire();
    // wl.release();

    wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();

    noise = PulseGenerator.getInstance();
    mover = Movement.getInstance();

    loadPrefs();

    mTorchMode = false;

    out = new ByteArrayOutputStream();

    setContentView(R.layout.main);

    if (sensorManager == null) {
      sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
    }

    startListening();

    mPreview = (SurfaceView) findViewById(R.id.preview);
    mHolder = mPreview.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    noise.pause();
  }
 /** Returns true if currently moving, ignoring the y movement. */
 public boolean isMovingIgnoreY() {
   return !velocityMovement.isStopped() && (velocity.x != 0 || velocity.z != 0);
 }
 /** Returns true if currently moving. */
 public boolean isMoving() {
   return !velocityMovement.isStopped() && !velocity.equals(0, 0, 0);
 }
 /** Returns true if the z axis is currently turning. */
 public boolean isTurningZ() {
   return !velocityAngleZ.isStopped();
 }
 /** Sets the angular speed of the z axis over the specified time. */
 public void setAngleVelocityZ(float speed, long time) {
   velocityAngleZ.set(speed, time);
 }
  public static void run(RobotController rc) {
    sightRadius = RobotType.SOLDIER.sensorRadiusSquared;
    attackRadius = RobotType.SOLDIER.attackRadiusSquared;
    myTeam = rc.getTeam();
    enemyTeam = myTeam.opponent();
    while (true) {
      try {
        numEnemySoldiers = 0;
        totalEnemySoldierHealth = 0;
        myLoc = rc.getLocation();
        nearbyAllies = rc.senseNearbyRobots(sightRadius, myTeam);
        nearbyEnemies = rc.senseHostileRobots(myLoc, sightRadius);
        newArchonLoc = null;

        // clear bad locations
        resetLocations(rc);
        // read messages and get destination
        readMessages(rc);
        // heal if need (and set the archon destination to go to)
        setRetreatingStatus(rc, nearbyEnemies);

        // Remove turret locations that you can see are not there.
        // Does NOT remove turret locations due to broadcasts. Already done in read messages.
        removeTurretLocations(rc);

        if (newArchonLoc != null) {
          nearestArchonLocation = newArchonLoc;
        }

        rc.setIndicatorString(2, "Round: " + rc.getRoundNum() + ", rushing: " + rush);
        // Reset rushing if turns since rush is > 20 and see no more enemies.
        if (rush && myLoc.distanceSquaredTo(rushLocation) <= 100) turnsSinceRush++;
        if (turnsSinceRush > 20) {
          if (rc.senseNearbyRobots(sightRadius, enemyTeam).length == 0) {
            turnsSinceRush = 0;
            rush = false;
          }
        }

        // When rushing, be mad aggressive.
        if (rush) {
          rushMicro(rc, nearbyEnemies);
        }
        // When retreating, retreat
        else if (healing) {
          if (rc.isCoreReady()) {
            if (nearestArchonLocation != null) {
              if (myLoc.distanceSquaredTo(nearestArchonLocation) > 13) {
                bugging.enemyAvoidMove(nearbyEnemies);
                // Get away from archons that are not too close together.
              } else if (myLoc.distanceSquaredTo(nearestArchonLocation) <= 2) {
                Direction radialDir = nearestArchonLocation.directionTo(myLoc);
                Direction awayDir = Movement.getBestMoveableDirection(radialDir, rc, 2);
                if (awayDir != Direction.NONE) {
                  rc.move(awayDir);
                }
              }
            }
          }
          // Make sure to attack people even when retreating.
          // Prioritize the closest enemy. Then the closest zombie.
          if (rc.isWeaponReady()) {
            // Attack the closest enemy. If there is not one, then attack the closest zombie
            int closestDist = 10000;
            RobotInfo target = null;
            for (RobotInfo hostile : nearbyEnemies) {
              int dist = myLoc.distanceSquaredTo(hostile.location);
              if (rc.canAttackLocation(hostile.location)) {
                // There is already is a target
                if (target != null) {
                  if (target.team == enemyTeam) {
                    // Target is already enemy, so prioritize the closest
                    if (hostile.team == enemyTeam) {
                      if (dist < closestDist) {
                        target = hostile;
                        closestDist = dist;
                      }
                    } // If hostile is not an enemy, not worth considering.
                  } else {
                    // Target is not on enemy team, so hostile is best choice!
                    if (hostile.team == enemyTeam) {
                      target = hostile;
                      closestDist = dist;
                      // Both are zombies, so just pick the closest.
                    } else {
                      if (dist < closestDist) {
                        target = hostile;
                        closestDist = dist;
                      }
                    }
                  }
                  // Set a target when there is not one.
                } else {
                  target = hostile;
                  closestDist = dist;
                }
              }
            }
            // We know that if there is a target, we can attack it.
            if (target != null) {
              rc.attackLocation(target.location);
            }
          }
        }

        // When viper infected and will die from the infection, do special micro
        else if (isViperInfected(rc)
            && (rc.getHealth() < rc.getViperInfectedTurns() * 2 || rc.getRoundNum() > 2100)) {
          viperInfectedMicro(rc);
        }

        // if there are enemies in range, we should focus on attack and micro
        else if (nearbyEnemies.length > 0) {
          if (shouldLure(rc, nearbyEnemies, nearbyAllies)) luringMicro(rc);
          else micro(rc);
        } else { // otherwise, we should always be moving somewhere
          moveSoldier(rc);
        }

        Clock.yield();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
  public static void zombieMicro(RobotController rc) throws GameActionException {
    boolean thereIsNonKitableZombie = false;
    RobotInfo closestEnemy = null;
    int closestDist = 10000;
    for (RobotInfo hostile : nearbyEnemies) {
      if (hostile.type == RobotType.FASTZOMBIE || hostile.type == RobotType.RANGEDZOMBIE) {
        thereIsNonKitableZombie = true;
      }
      int dist = myLoc.distanceSquaredTo(hostile.location);
      if (dist < closestDist) {
        closestDist = dist;
        closestEnemy = hostile;
      }
    }

    Direction d = myLoc.directionTo(closestEnemy.location);
    // if we're too close, move further away
    if (myLoc.distanceSquaredTo(closestEnemy.location) < 5 && rc.isCoreReady()) {
      Direction desired = d.opposite();
      Direction dir = Movement.getBestMoveableDirection(desired, rc, 1);
      if (dir != Direction.NONE) {
        rc.move(dir);
      } else if (shouldMine(rc, desired)) {
        rc.clearRubble(desired);
      } else if (shouldMine(rc, desired.rotateLeft())) {
        rc.clearRubble(desired.rotateLeft());
      } else if (shouldMine(rc, desired.rotateRight())) {
        rc.clearRubble(desired.rotateRight());
      }
    }
    if (!thereIsNonKitableZombie) {
      // Only move in closer if there is no non-kitable zombie
      if (myLoc.distanceSquaredTo(closestEnemy.location) > attackRadius
          && rc.isCoreReady()) { // if we are too far, we want to move closer
        // Desired direction is d.
        Direction dir = Movement.getBestMoveableDirection(d, rc, 1);
        if (dir != Direction.NONE) {
          rc.move(dir);
        } else if (shouldMine(rc, d)) {
          rc.clearRubble(d);
        } else if (shouldMine(rc, d.rotateLeft())) {
          rc.clearRubble(d.rotateLeft());
        } else if (shouldMine(rc, d.rotateRight())) {
          rc.clearRubble(d.rotateRight());
        } else { // probably meaning you are blocked by allies
          if (closestEnemy.type == RobotType.ZOMBIEDEN) {
            // It is likely that we wanted to go to that den, but possibly coincidence
            // If not a coincidence, bug there.
            if (bugging != null) {
              if (bugging.destination.equals(closestEnemy.location)) {
                bugging.turretAvoidMove(turretLocations);
                // If coincidence, set new bugging.
              } else {
                bugging = new Bugging(rc, closestEnemy.location);
                bugging.turretAvoidMove(turretLocations);
              }
            } else {
              bugging = new Bugging(rc, closestEnemy.location);
              bugging.turretAvoidMove(turretLocations);
            }
          }
        }
      }
    }
    if (rc.isWeaponReady() && rc.canAttackLocation(closestEnemy.location)) {
      broadcastingAttack(rc, closestEnemy);
    }
  }
  private static void rushMicro(RobotController rc, RobotInfo[] hostiles)
      throws GameActionException {
    // Prioritizes attacking turrets.
    RobotInfo bestEnemy = null;
    boolean canAttackBestEnemy = false;
    int bestEnemyDist = 10000; // only care if can't hit
    for (RobotInfo hostile : hostiles) {
      // Can attack this enemy.
      int dist = myLoc.distanceSquaredTo(hostile.location);
      // Summary:
      // Prioritizes enemies over zombies.
      // Prioritizes turret enemies over other enemies.
      // Prioritizes lowest health enemy last
      if (dist <= attackRadius) {
        if (bestEnemy != null) {
          if (bestEnemy.team == enemyTeam) { // best is already enemy
            if (hostile.team == enemyTeam) { // found an enemy
              if (countsAsTurret(bestEnemy.type)) {
                if (countsAsTurret(hostile.type)) {
                  // Take lowest health
                  if (bestEnemy.health > hostile.health) bestEnemy = hostile;
                }
              } else {
                if (countsAsTurret(hostile.type)) {
                  bestEnemy = hostile;
                } else {
                  // Take lowest health
                  if (bestEnemy.health > hostile.health) bestEnemy = hostile;
                }
              }
            }
          } else { // best is not an enemy!
            if (hostile.team == enemyTeam) { // found an enemy
              bestEnemy = hostile;
            } else {
              // Take lowest health
              if (bestEnemy.health > hostile.health) bestEnemy = hostile;
            }
          }
        } else {
          bestEnemy = hostile;
        }
        canAttackBestEnemy = true;
      } else {
        // Only update best enemy if you can't attack best enemy
        if (!canAttackBestEnemy) {
          if (bestEnemy != null) {
            // Pick the closest one
            if (bestEnemyDist > dist) {
              bestEnemyDist = dist;
              bestEnemy = hostile;
            }
          } else {
            bestEnemyDist = dist;
            bestEnemy = hostile;
          }
        }
      }
    }
    rc.setIndicatorString(0, "Round: " + rc.getRoundNum() + ", Best enemy: " + bestEnemy);
    if (rc.isCoreReady()) {
      // If there is a best enemy, attack him.
      if (bestEnemy != null) {
        // Move closer only if blocking someone.
        if (rc.canAttackLocation(bestEnemy.location)) {
          if (isBlockingSomeone(rc, bestEnemy.location)) {
            Direction desired = myLoc.directionTo(bestEnemy.location);
            Direction dir = Movement.getBestMoveableDirection(desired, rc, 2);
            if (dir != Direction.NONE) {
              rc.move(dir);
            } else if (shouldMine(rc, desired)) {
              rc.clearRubble(desired);
            } else if (shouldMine(rc, desired.rotateLeft())) {
              rc.clearRubble(desired.rotateLeft());
            } else if (shouldMine(rc, desired.rotateRight())) {
              rc.clearRubble(desired.rotateRight());
            }
          }
        }
        // If can't attack it, move closer!
        else {
          Direction desired = myLoc.directionTo(bestEnemy.location);
          Direction dir = Movement.getBestMoveableDirection(desired, rc, 2);
          if (dir != Direction.NONE) {
            rc.move(dir);
          } else if (shouldMine(rc, desired)) {
            rc.clearRubble(desired);
          } else if (shouldMine(rc, desired.rotateLeft())) {
            rc.clearRubble(dir.rotateLeft());
          } else if (shouldMine(rc, desired.rotateRight())) {
            rc.clearRubble(desired.rotateRight());
          }
        }
      }
      // Otherwise move closer to destination
      else {
        if (currentDestination != null) {
          RobotInfo info = null;
          if (rc.canSenseLocation(currentDestination)) {
            info = rc.senseRobotAtLocation(currentDestination);
          }
          if (info != null) {
            // If can attack it, just only move closer if blocking someone behind.
            if (rc.canAttackLocation(info.location)) {
              if (isBlockingSomeone(rc, currentDestination)) {
                Direction desired = myLoc.directionTo(currentDestination);
                Direction dir = Movement.getBestMoveableDirection(desired, rc, 2);
                if (dir != Direction.NONE) {
                  rc.move(dir);
                } else if (shouldMine(rc, desired)) {
                  rc.clearRubble(desired);
                } else if (shouldMine(rc, desired.rotateLeft())) {
                  rc.clearRubble(desired.rotateLeft());
                } else if (shouldMine(rc, desired.rotateRight())) {
                  rc.clearRubble(desired.rotateRight());
                }
              }
            }
            // If can't attack it, move closer!
            else {
              Direction desired = myLoc.directionTo(currentDestination);
              Direction dir = Movement.getBestMoveableDirection(desired, rc, 2);
              if (dir != Direction.NONE) {
                rc.move(dir);
              } else if (shouldMine(rc, desired)) {
                rc.clearRubble(desired);
              } else if (shouldMine(rc, desired.rotateLeft())) {
                rc.clearRubble(desired.rotateLeft());
              } else if (shouldMine(rc, desired.rotateRight())) {
                rc.clearRubble(desired.rotateRight());
              }
            }
          }
          // If not there, just move closer.
          else {
            Direction desired = myLoc.directionTo(currentDestination);
            Direction dir = Movement.getBestMoveableDirection(desired, rc, 2);
            if (dir != Direction.NONE) {
              rc.move(dir);
            } else if (shouldMine(rc, desired)) {
              rc.clearRubble(desired);
            } else if (shouldMine(rc, desired.rotateLeft())) {
              rc.clearRubble(desired.rotateLeft());
            } else if (shouldMine(rc, desired.rotateRight())) {
              rc.clearRubble(desired.rotateRight());
            }
          }
        }
      }
    }

    // Attack whenever you can.
    if (bestEnemy != null) {
      if (rc.isWeaponReady()) {
        if (rc.canAttackLocation(bestEnemy.location)) {
          broadcastingAttack(rc, bestEnemy);
        }
      }
    }
  }