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(); }
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; }
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); }
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); }
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(); }
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; }
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); }
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; }
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); }
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); } }