Пример #1
0
    public void onHitWall(HitWallEvent event) {
      double angle = peer.getBodyHeading() + event.getBearingRadians();

      hitWallAngle = (int) (Math.toDegrees(Utils.normalAbsoluteAngle(angle)) + 0.5);
      hitWallBearing = (int) (event.getBearing() + 0.5);
      JuniorRobot.this.onHitWall();
    }
Пример #2
0
  private static double getAcceleration(
      LXXRobotState robot, double turnRateRadians, double robotHeading) {
    final double speed = min(robot.getVelocityModule(), Rules.MAX_VELOCITY);
    final double acceleratedSpeed = min(speed + 1, Rules.MAX_VELOCITY);
    final double deceleratedSpeed1 = max(speed - 1, 0);
    final double newHeading = Utils.normalAbsoluteAngle(robotHeading + turnRateRadians);
    final int acceleration;
    if (robot
        .getBattleField()
        .contains(robot.project(newHeading, LXXUtils.getStopDistance(acceleratedSpeed) + 12))) {
      acceleration = 1;
    } else if (robot
        .getBattleField()
        .contains(robot.project(newHeading, LXXUtils.getStopDistance(speed) + 12))) {
      acceleration = 0;
    } else if (robot
        .getBattleField()
        .contains(robot.project(newHeading, LXXUtils.getStopDistance(deceleratedSpeed1) + 12))) {
      acceleration = -1;
    } else {
      acceleration = -2;
    }

    if (robot.getVelocityModule() + acceleration > Rules.MAX_VELOCITY) {
      return Rules.MAX_VELOCITY - robot.getVelocityModule();
    }
    if (robot.getVelocityModule() + acceleration < 0) {
      return -robot.getVelocityModule();
    }

    return acceleration;
  }
Пример #3
0
  public void onScannedRobot(ScannedRobotEvent e) {
    robotLocation = new Point2D.Double(getX(), getY());
    enemyAbsoluteBearing = getHeadingRadians() + e.getBearingRadians();
    enemyDistance = e.getDistance();
    enemyLocation = vectorToLocation(enemyAbsoluteBearing, enemyDistance, robotLocation);

    // Change direction at random
    if (Math.random() < 0.015) {
      movementLateralAngle *= -1;
    }
    move();
    execute();

    // radar
    setTurnRadarRightRadians(
        Utils.normalRelativeAngle(enemyAbsoluteBearing - getRadarHeadingRadians()) * 2);

    /*
     * Circular Gun from wiki
     */
    double absBearing = e.getBearingRadians() + getHeadingRadians();

    // Finding the heading and heading change.
    double enemyHeading = e.getHeadingRadians();
    double enemyHeadingChange = enemyHeading - oldEnemyHeading;
    oldEnemyHeading = enemyHeading;

    double deltaTime = 0;
    double predictedX = getX() + e.getDistance() * Math.sin(absBearing);
    double predictedY = getY() + e.getDistance() * Math.cos(absBearing);
    while ((++deltaTime) * BULLET_SPEED
        < Point2D.Double.distance(getX(), getY(), predictedX, predictedY)) {

      // Add the movement we think our enemy will make to our enemy's current X and Y
      predictedX += Math.sin(enemyHeading) * (e.getVelocity());
      predictedY += Math.cos(enemyHeading) * (e.getVelocity());

      // Find our enemy's heading changes.
      enemyHeading += enemyHeadingChange;

      // If our predicted coordinates are outside the walls, put them 18
      // distance units away from the walls as we know
      // that that is the closest they can get to the wall (Bots are
      // non-rotating 36*36 squares).
      predictedX = Math.max(Math.min(predictedX, getBattleFieldWidth() - 18), 18);
      predictedY = Math.max(Math.min(predictedY, getBattleFieldHeight() - 18), 18);
    }
    // Find the bearing of our predicted coordinates from us.
    double aim = Utils.normalAbsoluteAngle(Math.atan2(predictedX - getX(), predictedY - getY()));

    // Aim and fire.
    setTurnGunRightRadians(Utils.normalRelativeAngle(aim - getGunHeadingRadians()));
    setFire(BULLET_POWER);

    setTurnRadarRightRadians(Utils.normalRelativeAngle(absBearing - getRadarHeadingRadians()) * 2);
  }
Пример #4
0
  private final Bullet setFireImpl(double power) {
    if (Double.isNaN(power)) {
      println("SYSTEM: You cannot call fire(NaN)");
      return null;
    }
    if (getGunHeatImpl() > 0 || getEnergyImpl() == 0) {
      return null;
    }

    power = min(getEnergyImpl(), min(max(power, Rules.MIN_BULLET_POWER), Rules.MAX_BULLET_POWER));

    Bullet bullet;
    BulletCommand wrapper;
    Event currentTopEvent = eventManager.getCurrentTopEvent();

    nextBulletId++;

    if (currentTopEvent != null
        && currentTopEvent.getTime() == status.getTime()
        && !statics.isAdvancedRobot()
        && status.getGunHeadingRadians() == status.getRadarHeadingRadians()
        && ScannedRobotEvent.class.isAssignableFrom(currentTopEvent.getClass())) {
      // this is angle assisted bullet
      ScannedRobotEvent e = (ScannedRobotEvent) currentTopEvent;
      double fireAssistAngle =
          Utils.normalAbsoluteAngle(status.getHeadingRadians() + e.getBearingRadians());

      bullet =
          new Bullet(
              fireAssistAngle, getX(), getY(), power, statics.getName(), null, true, nextBulletId);
      wrapper = new BulletCommand(power, true, fireAssistAngle, nextBulletId);
    } else {
      // this is normal bullet
      bullet =
          new Bullet(
              status.getGunHeadingRadians(),
              getX(),
              getY(),
              power,
              statics.getName(),
              null,
              true,
              nextBulletId);
      wrapper = new BulletCommand(power, false, 0, nextBulletId);
    }

    firedEnergy += power;
    firedHeat += Rules.getGunHeat(power);

    commands.getBullets().add(wrapper);

    bullets.put(nextBulletId, bullet);

    return bullet;
  }
  private double getBodyTurn() {
    // а вот вычисление угла поворота посложее
    final double alphaToMe = angleTo(enemyX, enemyY, getX(), getY());

    // определяем угловое направление относительно противника (по часовой стрелке, либо против) ...
    final double lateralDirection =
        signum(
            (getVelocity() != 0 ? getVelocity() : 1)
                * Math.sin(Utils.normalRelativeAngle(getHeadingRadians() - alphaToMe)));
    // получаем желаемое направление движения
    final double desiredHeading =
        Utils.normalAbsoluteAngle(alphaToMe + Math.PI / 2 * lateralDirection);
    // нормализуем направление по скорости
    final double normalHeading =
        getVelocity() >= 0
            ? getHeadingRadians()
            : Utils.normalAbsoluteAngle(getHeadingRadians() + Math.PI);
    // и возвращаем угол поворта
    return Utils.normalRelativeAngle(desiredHeading - normalHeading);
  }
Пример #6
0
    public void onScannedRobot(ScannedRobotEvent event) {
      scannedDistance = (int) (event.getDistance() + 0.5);
      scannedEnergy = Math.max(1, (int) (event.getEnergy() + 0.5));
      scannedAngle =
          (int)
              (Math.toDegrees(
                      Utils.normalAbsoluteAngle(peer.getBodyHeading() + event.getBearingRadians()))
                  + 0.5);
      scannedBearing = (int) (event.getBearing() + 0.5);
      scannedHeading = (int) (event.getHeading() + 0.5);
      scannedVelocity = (int) (event.getVelocity() + 0.5);

      JuniorRobot.this.onScannedRobot();
    }
Пример #7
0
  public double getAbsoluteAimAngle(
      Wave aimWave, BotScan scan, BotScan enemyScan, double bulletPower) {

    if (_lastFireTime == aimWave.fireTime) {
      return _lastAimAngle;
    }

    _lastAimAngle =
        Utils.normalAbsoluteAngle(
            aimWave.absBearingRadians
                + aimWave.guessAngleFromIndex(getAimBin(aimWave, scan, enemyScan, bulletPower)));

    _lastFireTime = aimWave.fireTime;

    return _lastAimAngle;
  }
Пример #8
0
  public static MovementDecision toMovementDecision(
      LXXRobotState robot, double targetHeading, MovementDirection movementDirection) {
    final double robotHeading =
        movementDirection == MovementDirection.FORWARD
            ? robot.getHeadingRadians()
            : Utils.normalAbsoluteAngle(robot.getHeadingRadians() + LXXConstants.RADIANS_180);
    final double neededTurnRateRadians = Utils.normalRelativeAngle(targetHeading - robotHeading);
    double turnRateRadians = neededTurnRateRadians;
    final double speed = robot.getVelocityModule();
    final double acceleratedSpeed = min(speed + 1, Rules.MAX_VELOCITY);
    if (abs(turnRateRadians) > Rules.getTurnRateRadians(acceleratedSpeed)) {
      turnRateRadians = Rules.getTurnRateRadians(acceleratedSpeed) * signum(turnRateRadians);
    }
    final double acceleration = getAcceleration(robot, turnRateRadians, robotHeading);
    turnRateRadians =
        min(
                abs(neededTurnRateRadians),
                abs(
                    Rules.getTurnRateRadians(
                        LXXUtils.limit(0, speed + acceleration, Rules.MAX_VELOCITY))))
            * signum(turnRateRadians);

    return new MovementDecision(acceleration, turnRateRadians, movementDirection);
  }
Пример #9
0
  public MovSimStat[] futurePos(
      int steps,
      double x,
      double y,
      double velocity,
      double maxVelocity,
      double heading,
      double distanceRemaining,
      double angleToTurn,
      double maxTurnRate,
      double battleFieldW,
      double battleFieldH) {
    // maxTurnRate in degrees
    MovSimStat[] pos = new MovSimStat[steps];
    double acceleration = 0;
    boolean slowingDown = false;
    double moveDirection;

    maxTurnRate = Math.toRadians(maxTurnRate);
    if (distanceRemaining == 0) moveDirection = 0;
    else if (distanceRemaining < 0.0) moveDirection = -1;
    else moveDirection = 1;

    // heading, accel, velocity, distance
    for (int i = 0; i < steps; i++) {
      // heading
      double lastHeading = heading;
      double turnRate =
          Math.min(
              maxTurnRate,
              ((0.4 + 0.6 * (1.0 - (Math.abs(velocity) / systemMaxVelocity))) * systemMaxTurnRate));
      if (angleToTurn > 0.0) {
        if (angleToTurn < turnRate) {
          heading += angleToTurn;
          angleToTurn = 0.0;
        } else {
          heading += turnRate;
          angleToTurn -= turnRate;
        }
      } else if (angleToTurn < 0.0) {
        if (angleToTurn > -turnRate) {
          heading += angleToTurn;
          angleToTurn = 0.0;
        } else {
          heading -= turnRate;
          angleToTurn += turnRate;
        }
      }
      heading = Utils.normalAbsoluteAngle(heading);
      // movement
      if (distanceRemaining != 0.0 || velocity != 0.0) {
        // lastX = x; lastY = y;
        if (!slowingDown && moveDirection == 0) {
          slowingDown = true;
          if (velocity > 0.0) moveDirection = 1;
          else if (velocity < 0.0) moveDirection = -1;
          else moveDirection = 0;
        }
        double desiredDistanceRemaining = distanceRemaining;
        if (slowingDown) {
          if (moveDirection == 1 && distanceRemaining < 0.0) desiredDistanceRemaining = 0.0;
          else if (moveDirection == -1 && distanceRemaining > 1.0) desiredDistanceRemaining = 0.0;
        }
        double slowDownVelocity =
            (double)
                (int)
                    (maxBraking
                        / 2.0
                        * ((Math.sqrt(4.0 * Math.abs(desiredDistanceRemaining) + 1.0)) - 1.0));
        if (moveDirection == -1) slowDownVelocity = -slowDownVelocity;
        if (!slowingDown) {
          if (moveDirection == 1) {
            if (velocity < 0.0) acceleration = maxBraking;
            else acceleration = maxAcceleration;
            if (velocity + acceleration > slowDownVelocity) slowingDown = true;
          } else if (moveDirection == -1) {
            if (velocity > 0.0) acceleration = -maxBraking;
            else acceleration = -maxAcceleration;
            if (velocity + acceleration < slowDownVelocity) slowingDown = true;
          }
        }
        if (slowingDown) {
          if (distanceRemaining != 0.0
              && Math.abs(velocity) <= maxBraking
              && Math.abs(distanceRemaining) <= maxBraking) slowDownVelocity = distanceRemaining;
          double perfectAccel = slowDownVelocity - velocity;
          if (perfectAccel > maxBraking) perfectAccel = maxBraking;
          else if (perfectAccel < -maxBraking) perfectAccel = -maxBraking;
          acceleration = perfectAccel;
        }
        if (velocity > maxVelocity || velocity < -maxVelocity) acceleration = 0.0;
        velocity += acceleration;
        if (velocity > maxVelocity) velocity -= Math.min(maxBraking, velocity - maxVelocity);
        if (velocity < -maxVelocity) velocity += Math.min(maxBraking, -velocity - maxVelocity);
        double dx = velocity * Math.sin(heading);
        double dy = velocity * Math.cos(heading);
        x += dx;
        y += dy;
        // boolean updateBounds = false;
        // if (dx != 0.0 || dy != 0.0) updateBounds = true;
        if (slowingDown && velocity == 0.0) {
          distanceRemaining = 0.0;
          moveDirection = 0;
          slowingDown = false;
          acceleration = 0.0;
        }
        // if (updateBounds) updateBoundingBox();
        distanceRemaining -= velocity;
        if (x < 18 || y < 18 || x > battleFieldW - 18 || y > battleFieldH - 18) {
          distanceRemaining = 0;
          angleToTurn = 0;
          velocity = 0;
          moveDirection = 0;
          x = Math.max(18, Math.min(battleFieldW - 18, x));
          y = Math.max(18, Math.min(battleFieldH - 18, y));
        }
      }
      // add position
      pos[i] =
          new MovSimStat(x, y, velocity, heading, Utils.normalRelativeAngle(heading - lastHeading));
    }
    return pos;
  }
Пример #10
-1
  public void aceInTheHole(ScannedRobotEvent e) {
    double bulletPower = Math.min(3.0, getEnergy());
    double myX = getX();
    double myY = getY();
    double absoluteBearing = getHeadingRadians() + e.getBearingRadians();
    double enemyX = getX() + e.getDistance() * Math.sin(absoluteBearing);
    double enemyY = getY() + e.getDistance() * Math.cos(absoluteBearing);
    double enemyHeading = e.getHeadingRadians();
    double enemyVelocity = e.getVelocity();

    double deltaTime = 0;
    double battleFieldHeight = getBattleFieldHeight(), battleFieldWidth = getBattleFieldWidth();
    double predictedX = enemyX, predictedY = enemyY;
    while ((++deltaTime) * (20.0 - 3.0 * bulletPower)
        < Point2D.Double.distance(myX, myY, predictedX, predictedY)) {
      predictedX += Math.sin(enemyHeading) * enemyVelocity;
      predictedY += Math.cos(enemyHeading) * enemyVelocity;
      if (predictedX < 18.0
          || predictedY < 18.0
          || predictedX > battleFieldWidth - 18.0
          || predictedY > battleFieldHeight - 18.0) {
        predictedX = Math.min(Math.max(18.0, predictedX), battleFieldWidth - 18.0);
        predictedY = Math.min(Math.max(18.0, predictedY), battleFieldHeight - 18.0);
        break;
      }
    }
    double theta = Utils.normalAbsoluteAngle(Math.atan2(predictedX - getX(), predictedY - getY()));

    setTurnRadarRightRadians(Utils.normalRelativeAngle(absoluteBearing - getRadarHeadingRadians()));
    setTurnGunRightRadians(Utils.normalRelativeAngle(theta - getGunHeadingRadians()));
    fire(bulletPower);
  }
Пример #11
-1
  private void doShooting() {
    PositionFinder p = new PositionFinder(enemies, this);
    en = p.findNearest();
    if (en == null) return;

    Point2D myPos = new Point2D.Double(getX(), getY());

    if (HoT) {
      /* Perform head on target for gun movement */
      aimingPoint = new Point2D.Double(en.getX(), en.getY());
      double turnGunAmt = (getHeadingRadians() + en.getBearingRadians() - getGunHeadingRadians());
      turnGunAmt = Utils.normalRelativeAngle(turnGunAmt);
      setTurnGunRightRadians(turnGunAmt);
    } else {
      /* Perform circular targeting */
      Rectangle2D battlefield =
          new Rectangle2D.Double(0, 0, getBattleFieldWidth(), getBattleFieldHeight());
      long when = calcTimeToReachEnemy();
      aimingPoint = org.pattern.utils.Utils.getFuturePoint(en, when);
      if (!battlefield.contains(aimingPoint)) {
        HoT = true;
        return;
      }
      double theta =
          Utils.normalAbsoluteAngle(
              Math.atan2(aimingPoint.getX() - getX(), aimingPoint.getY() - getY()));
      setTurnGunRightRadians(Utils.normalRelativeAngle(theta - getGunHeadingRadians()));
    }

    if (getGunHeat() == 0) {
      double firePower = 3.0;
      fire(firePower);
    }
  }