public void evaluateDistancingControl() { double powerTwoHitPercentageThreshold; if (_robot.getRoundNum() < 2) { _desiredDistance = 420; _fearDistance = 175; _smoothAwayDistance = 75; } else if (normalizedEnemyHitPercentage() > (powerTwoHitPercentageThreshold = 7.5)) { _desiredDistance = 525 + (Math.max((ScanLog.avgEnemyPower() - 2), 0) * 165); _fearDistance = 250; _smoothAwayDistance = 75; } else if (normalizedEnemyHitPercentage() > (powerTwoHitPercentageThreshold = 3)) { _desiredDistance = 450 + (Math.max((ScanLog.avgEnemyPower() - 2), 0) * 150); _fearDistance = 175; _smoothAwayDistance = 75; } else { _desiredDistance = 420; _fearDistance = 0; _smoothAwayDistance = 0; } if (_robot.getRoundNum() < 2 || normalizedEnemyHitPercentage() > 7.5) { _currentDistancer = _aggressiveDistancer; } else { _currentDistancer = _subtleDistancer; } }
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); }
/** Computes a value within min and max */ public static double limit(double min, double val, double max) { return Math.max(min, Math.min(val, max)); }
public static int getVelocitySegment(double velocity) { return (int) Math.max(0, velocity - 1); }
public static int getBearingSegment(double bearing) { int index = (int) (bearing / (2 * Math.PI) * (BEARINGS)); return Math.max(0, Math.min(BEARINGS - 1, index)); }
public double checkDanger( RobotState startState, int movementOption, boolean previouslyMovingClockwise, int surfableWaveIndex, int recursionLevels) { if (surfableWaveIndex >= recursionLevels) { return 0; } boolean predictClockwiseOrNot; if (movementOption == CLOCKWISE_OPTION) { predictClockwiseOrNot = true; } else if (movementOption == COUNTERCLOCKWISE_OPTION) { predictClockwiseOrNot = false; } else { predictClockwiseOrNot = previouslyMovingClockwise; } Wave surfWave = findSurfableWave(surfableWaveIndex); if (surfWave == null) { if (surfableWaveIndex == FIRST_WAVE) { double nonSurfableWaveDistance = 150; surfWave = findNonSurfableWave(nonSurfableWaveDistance); } if (surfWave == null) { return NO_SURFABLE_WAVES; } } /* Color drawColor = Color.white; if (surfableWaveIndex != 0 || movementOption == STOP_OPTION) { drawColor = Color.blue; } */ double waveHitInterceptOffset = surfWave.bulletVelocity() + BOT_HALF_WIDTH; double wavePassedInterceptOffset = surfWave.bulletVelocity(); RobotState predictedState = startState; RobotState dangerState = startState; boolean wavePassed = false; boolean waveHit = false; double maxVelocity = (movementOption == STOP_OPTION) ? 0 : 8; do { double orbitAbsBearing = DUtils.absoluteBearing(surfWave.sourceLocation, predictedState.location); double orbitDistance = surfWave.sourceLocation.distance(predictedState.location); double attackAngle = _currentDistancer.attackAngle(orbitDistance, _desiredDistance); boolean clockwiseSmoothing = predictClockwiseOrNot; if (orbitDistance < _smoothAwayDistance) { clockwiseSmoothing = !clockwiseSmoothing; } predictedState = DUtils.nextPerpendicularWallSmoothedLocation( predictedState.location, orbitAbsBearing, predictedState.velocity, maxVelocity, predictedState.heading, attackAngle, clockwiseSmoothing, predictedState.time, DUtils.battleField, DUtils.battleFieldWidth, DUtils.battleFieldHeight, _wallStick, DUtils.OBSERVE_WALL_HITS); if (!waveHit && surfWave.wavePassed( predictedState.location, predictedState.time, waveHitInterceptOffset)) { dangerState = predictedState; waveHit = true; } if (!wavePassed && surfWave.wavePassed( predictedState.location, predictedState.time, wavePassedInterceptOffset)) { wavePassed = true; } } while (!wavePassed); // drawPoint(predictedState.location, drawColor); double danger = getBinScore(surfWave, dangerState.location); danger *= DUtils.bulletDamage(surfWave.bulletPower); double currentDistanceToWaveSource = ScanLog.myLocation().distance(surfWave.sourceLocation); double currentDistanceToWave = currentDistanceToWaveSource - surfWave.distanceTraveled(_robot.getTime()); double timeToImpact = currentDistanceToWave / DUtils.bulletVelocity(surfWave.bulletPower); if (_flattenerEnabled) { danger /= DUtils.square(timeToImpact); } else { danger /= timeToImpact; } double nextCounterClockwiseDanger = checkDanger( predictedState, COUNTERCLOCKWISE_OPTION, predictClockwiseOrNot, surfableWaveIndex + 1, recursionLevels); double nextStopDanger = checkDanger( predictedState, STOP_OPTION, predictClockwiseOrNot, surfableWaveIndex + 1, recursionLevels); double nextClockwiseDanger = checkDanger( predictedState, CLOCKWISE_OPTION, predictClockwiseOrNot, surfableWaveIndex + 1, recursionLevels); danger += Math.min(nextCounterClockwiseDanger, Math.min(nextStopDanger, nextClockwiseDanger)); // danger += Math.min(nextCounterClockwiseDanger, nextClockwiseDanger); if (surfableWaveIndex == FIRST_WAVE) { double predictedDistanceToWaveSource = surfWave.sourceLocation.distance(predictedState.location); double predictedDistanceToEnemy = ScanLog.enemyLocation().distance(predictedState.location); double shorterDistance = Math.min(predictedDistanceToWaveSource, predictedDistanceToEnemy); double distancingDangerBase = Math.max(currentDistanceToWaveSource / shorterDistance, .99); double distancingDangerExponent = shorterDistance > _fearDistance ? NORMAL_DISTANCING_EXPONENT : FEARFUL_DISTANCING_EXPONENT; danger *= Math.pow(distancingDangerBase, distancingDangerExponent); } return danger; }