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 Wave findSurfableWave(int waveIndex) { int searchWaveIndex = 0; long currentTime = _robot.getTime(); for (int x = 0; x < _waves.size(); x++) { Wave w = (Wave) _waves.get(x); double distanceToWaveSource = ScanLog.myLocation().distance(w.sourceLocation); double distanceToWave = distanceToWaveSource - w.distanceTraveled(currentTime); if (w.firingWave && !w.processedBulletHit && distanceToWave > w.bulletVelocity()) { if (searchWaveIndex == waveIndex) { // drawCircle(w.sourceLocation, // w.distanceTraveled(currentTime + 1), Color.green); // drawLine(w.sourceLocation, // DUtils.project(w.sourceLocation, w.absBearingRadians, // w.distanceTraveled(currentTime + 1)), // Color.blue); return w; } else { searchWaveIndex++; } } } return null; }
public void fireWave(boolean isFiringWave) { int timeSinceEnemyFired = (int) ScanLog.getLastFireOffset(); double bulletPower = ScanLog.getLastEnemyBulletPower(); try { Point2D.Double myTargetLocation = ScanLog.getLocation(timeSinceEnemyFired); Point2D.Double enemyFireLocation = ScanLog.getEnemyLocation(timeSinceEnemyFired); BotScan enemySegmentationScan = ScanLog.getEnemyScan(timeSinceEnemyFired + 1); Wave enemyWave = new Wave( enemySegmentationScan, enemyFireLocation, myTargetLocation, _robot.getTime() - timeSinceEnemyFired, isFiringWave ? Wave.FIRING_WAVE : Wave.NON_FIRING_WAVE, enemySegmentationScan.getAbsBearingRadians(), bulletPower, "Surf Wave", Wave.TRADITIONAL_MAX_ESCAPE_ANGLE, enemySegmentationScan.getHeadingRadians(), enemySegmentationScan.getVelocity(), _lastEnemyWaveOrientation, SURF_ORIENTATION_VELOCITY_THRESHOLD); _waves.add(enemyWave); _lastEnemyWaveOrientation = enemyWave.orientation; } catch (IndexOutOfBoundsException noScanDataYet) { } }
/* public void onPaint(Graphics2D g) { Iterator i = _renderables.iterator(); while(i.hasNext()){ Renderable r = (Renderable) i.next(); r.render(g); } _renderables.clear(); } */ public Wave processBulletReturnFiringWave(Bullet bullet, long currentTime) { int tightMatchDistanceThreshold = 50; Wave hitWave = DUtils.findClosestWave( _waves, new Point2D.Double(bullet.getX(), bullet.getY()), _robot.getTime(), DUtils.ANY_WAVE, DUtils.FIRING_WAVE, tightMatchDistanceThreshold); if (hitWave == null) { return NO_WAVE_FOUND; } for (int x = 0; x < _bulletHitRegisters.size(); x++) { BulletHitRegister bhr = (BulletHitRegister) _bulletHitRegisters.get(x); bhr.registerBulletHit(bullet, hitWave, currentTime); } hitWave.processedBulletHit = true; return hitWave; }
public DookiCape(AdvancedRobot robot, boolean mc) { DUtils.setBattleFieldWidth(robot.getBattleFieldWidth()); DUtils.setBattleFieldHeight(robot.getBattleFieldHeight()); _mcMode = mc; _waves = new ArrayList(); _waveRegisters = new ArrayList(); _bulletHitRegisters = new ArrayList(); _flattenerEnabled = false; _currentDistancer = _subtleDistancer = new SubtleDistancing(); _aggressiveDistancer = new AggressiveDistancing(); _renderables = new Vector(); initializeSurfBuffers(); reset(robot); }
public void evaluateFlattener() { double powerTwoHitPercentageThreshold; if (_robot.getRoundNum() >= 20) { setFlattener( normalizedEnemyHitPercentage() > ((powerTwoHitPercentageThreshold = 9.8)) && _weightedEnemyShotsFired > 100); } else if (_robot.getRoundNum() >= 10) { setFlattener( normalizedEnemyHitPercentage() > ((powerTwoHitPercentageThreshold = 10.5)) && _weightedEnemyShotsFired > 50); } else if (_robot.getRoundNum() >= 5) { setFlattener( normalizedEnemyHitPercentage() > ((powerTwoHitPercentageThreshold = 13)) && normalizedEnemyHitPercentageLastRound() > (powerTwoHitPercentageThreshold = 14) && _weightedEnemyShotsFired > 20); } else { setFlattener(false); } }
public Wave findNonSurfableWave(double minDistanceToWave) { long currentTime = _robot.getTime(); for (int x = 0; x < _waves.size(); x++) { Wave w = (Wave) _waves.get(x); double distanceToWaveSource = ScanLog.myLocation().distance(w.sourceLocation); double distanceToWave = distanceToWaveSource - w.distanceTraveled(currentTime); if (!w.firingWave && distanceToWave > minDistanceToWave) { return w; } } return null; }
public void disableFlattener() { _flattenerEnabled = false; _waveRegisters.remove(_highStatBuffers); _waveRegisters.remove(_lowStatBuffers); if (_robot.getRoundNum() >= 3 && normalizedEnemyHitPercentage() < 4) { _highStatBuffers.setBulletHitWeight(0.2); _lowStatBuffers.setBulletHitWeight(0.2); } else { _highStatBuffers.setBulletHitWeight(1.0); _lowStatBuffers.setBulletHitWeight(1.0); } System.out.println("Curve Flattening disabled."); }
/** * Executes any pending actions, or continues executing actions that are in process. This call * returns after the actions have been started. * * <p>Note that advanced robots <em>must</em> call this function in order to execute pending set* * calls like e.g. {@code setVelocityRate()}, {@code setFire()}, {@code setTurnRate()} etc. * Otherwise, these calls will never get executed. * * <p>Any previous calls to "movement" functions outside of {@code RateControlRobot}, such as * {@code setAhead()}, {@code setTurnLeft()}, {@code setTurnRadarLeftRadians()} etc. will be * overridden when this method is called on this robot class. * * <p>In this example the robot will move while turning: * * <pre> * setVelocityRate(6); * setTurnRate(7); * * while (true) { * execute(); * } * </pre> */ @Override public void execute() { setMaxVelocity(velocityRate); if (velocityRate > 0) { setAhead(Double.POSITIVE_INFINITY); } else if (velocityRate < 0) { setBack(Double.POSITIVE_INFINITY); } else { setAhead(0); } setTurnGunRightRadians(gunRotationRate); setTurnRadarRightRadians(radarRotationRate); setTurnRightRadians(turnRate); super.execute(); }
public void checkActiveWaves() { long currentTime = _robot.getTime(); Point2D.Double myLocation = ScanLog.myLocation(); for (int x = 0; x < _waves.size(); x++) { Wave w = (Wave) _waves.get(x); if (w.processedWaveBreak) { if (w.wavePassed(myLocation, currentTime, Wave.INACTIVE_WAVE_OFFSET)) { _waves.remove(x--); } } else { if (w.wavePassed(myLocation, currentTime)) { processWave(w); } } } }
public void roundOver() { _lastRoundNormalizedHitPercentage = normalizedEnemyHitPercentageThisRound(); System.out.println(); System.out.println( "Enemy's hit % this round: " + ((int) ScanLog.getEnemyBulletHitsThisRound()) + " / " + ((int) ScanLog.getEnemyBulletsFiredThisRound()) + ", " + DUtils.round(ScanLog.getEnemyHitPercentageThisRound(), 2)); System.out.println( "Enemy's normalized hit % this round: " + DUtils.round(_weightedEnemyShotsHitThisRound, 2) + " / " + DUtils.round(_weightedEnemyShotsFiredThisRound, 0) + ", " + DUtils.round(_lastRoundNormalizedHitPercentage, 2)); System.out.println( "Enemy's cumulative hit %: " + ((int) ScanLog.getEnemyBulletHits()) + " / " + ((int) ScanLog.getEnemyBulletsFired()) + ", " + DUtils.round(ScanLog.getEnemyHitPercentage(), 2)); System.out.println( "Enemy's normalized cum hit %: " + DUtils.round(_weightedEnemyShotsHit, 2) + " / " + DUtils.round(_weightedEnemyShotsFired, 0) + ", " + DUtils.round(normalizedEnemyHitPercentage(), 2)); System.out.println("Curve Flattener: " + ((_flattenerEnabled) ? "Enabled" : "Disabled")); System.out.println("Total damage taken: " + DUtils.round(ScanLog.getBulletDamageTaken(), 2)); if (_mcMode) { System.out.println(); System.out.println( "MC score: " + DUtils.round( (100.0 - (ScanLog.getBulletDamageTaken() / (_robot.getRoundNum() + 1.0))), 3)); } }
public static void setBackAsFront(AdvancedRobot robot, double goAngle) { double angle = Utils.normalRelativeAngle(goAngle - robot.getHeadingRadians()); if (Math.abs(angle) > (Math.PI / 2)) { if (angle < 0) { robot.setTurnRightRadians(Math.PI + angle); } else { robot.setTurnLeftRadians(Math.PI - angle); } robot.setBack(100); } else { if (angle < 0) { robot.setTurnLeftRadians(-1 * angle); } else { robot.setTurnRightRadians(angle); } robot.setAhead(100); } }
public void surf() { RobotState currentState = new RobotState( ScanLog.myLocation(), _robot.getHeadingRadians(), _robot.getVelocity(), _robot.getTime()); boolean goingClockwise = (_lastMovementChoice == CLOCKWISE_OPTION); double orbitCounterClockwiseDanger = checkDanger( currentState, COUNTERCLOCKWISE_OPTION, goingClockwise, FIRST_WAVE, WAVES_TO_SURF); double stopDanger = checkDanger(currentState, STOP_OPTION, goingClockwise, FIRST_WAVE, WAVES_TO_SURF); double orbitClockwiseDanger = checkDanger(currentState, CLOCKWISE_OPTION, goingClockwise, FIRST_WAVE, WAVES_TO_SURF); int goOrientation = _lastMovementChoice; Wave orbitWave = findSurfableWave(FIRST_WAVE); double orbitAbsBearing, distanceToClosestWaveSource; try { distanceToClosestWaveSource = ScanLog.myLocation().distance(orbitWave.sourceLocation); orbitAbsBearing = DUtils.absoluteBearing(orbitWave.sourceLocation, ScanLog.myLocation()); } catch (NullPointerException noSurfableWaves) { distanceToClosestWaveSource = ScanLog.getLastDistance(); orbitAbsBearing = ScanLog.getLastEnemyScan().getAbsBearingRadians(); } double goAngle, attackAngle; if (stopDanger == NO_SURFABLE_WAVES) { attackAngle = -1.047; _robot.setMaxVelocity(8); double goAngleCcw = orbitAbsBearing + (COUNTERCLOCKWISE_OPTION * ((Math.PI / 2) + attackAngle)); goAngleCcw = wallSmoothing( ScanLog.myLocation(), goAngleCcw, COUNTERCLOCKWISE_OPTION, distanceToClosestWaveSource); double goAngleCw = orbitAbsBearing + (CLOCKWISE_OPTION * ((Math.PI / 2) + attackAngle)); goAngleCw = wallSmoothing( ScanLog.myLocation(), goAngleCw, CLOCKWISE_OPTION, distanceToClosestWaveSource); if (Math.abs(Utils.normalRelativeAngle(goAngleCw - orbitAbsBearing)) < Math.abs(Utils.normalRelativeAngle(goAngleCcw - orbitAbsBearing))) { goOrientation = CLOCKWISE_OPTION; goAngle = goAngleCw; } else { goOrientation = COUNTERCLOCKWISE_OPTION; goAngle = goAngleCcw; } } else { _robot.setMaxVelocity(8); attackAngle = _currentDistancer.attackAngle(distanceToClosestWaveSource, _desiredDistance); if (ScanLog.enemyIsRammer() && ScanLog.getLastDistance() < 300 && orbitWave != NO_WAVE_FOUND) { if (Utils.normalRelativeAngle( DUtils.absoluteBearing(ScanLog.myLocation(), orbitWave.sourceLocation) - ScanLog.getLastScan().getAbsBearingRadians()) > 0) { goOrientation = -1; } else { goOrientation = 1; } } else if (stopDanger <= orbitCounterClockwiseDanger && stopDanger <= orbitClockwiseDanger && !ScanLog.enemyIsRammer()) { _robot.setMaxVelocity(0); } else { if (orbitClockwiseDanger < orbitCounterClockwiseDanger) { goOrientation = CLOCKWISE_OPTION; } else { goOrientation = COUNTERCLOCKWISE_OPTION; } } goAngle = orbitAbsBearing + (goOrientation * ((Math.PI / 2) + attackAngle)); goAngle = wallSmoothing(ScanLog.myLocation(), goAngle, goOrientation, distanceToClosestWaveSource); } DUtils.setBackAsFront(_robot, goAngle); _lastMovementChoice = goOrientation; }
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; }