SurfMover { void surf(RobotState myRobotState, MoveEnemy duelEnemy, Wave surfWave, int wavesToSurf, boolean painting) { if (surfWave != _lastWaveSurfed) { duelEnemy.clearNeighborCache(); _lastWaveSurfed = surfWave; _lastSurfDestination = null; _stopDestination = null; } boolean goingClockwise = (_lastSurfOption == SurfOption.CLOCKWISE); updateSurfDangers(myRobotState, duelEnemy, wavesToSurf, goingClockwise); double counterDanger = _surfOptionDangers.get(SurfOption.COUNTER_CLOCKWISE); double stopDanger = _surfOptionDangers.get(SurfOption.STOP); double clockwiseDanger = _surfOptionDangers.get(SurfOption.CLOCKWISE); Point2D.Double surfDestination; if (stopDanger <= counterDanger && stopDanger <= clockwiseDanger) { if (_stopDestination == null) { _stopDestination = _surfOptionDestinations.get(_lastSurfOption); } surfDestination = _stopDestination; _robot.setMaxVelocity(0); _lastSurfDestination = null; } else { _robot.setMaxVelocity(8); _lastSurfOption = (clockwiseDanger < counterDanger) ? SurfOption.CLOCKWISE : SurfOption.COUNTER_CLOCKWISE; surfDestination = _surfOptionDestinations.get(_lastSurfOption); _lastSurfDestination = surfDestination; _stopDestination = null; } double goAngle = DiaUtils.absoluteBearing(myRobotState.location, surfDestination); goAngle = wallSmoothing(myRobotState.location, goAngle, _lastSurfOption); if (painting) { duelEnemy.drawRawWaves(_robot.getTime()); for (int x = 0; x < WAVES_TO_DRAW; x++) { drawWaveDangers(myRobotState, duelEnemy, x); drawWaveShadows(myRobotState, duelEnemy, x); } } DiaUtils.setBackAsFront(_robot, goAngle); } SurfMover(AdvancedRobot robot, BattleField battleField,
      Collection<RoboGraphic> renderables, OutputStream out); void initRound(); void move(RobotState myRobotState, MoveEnemy duelEnemy,
      int wavesToSurf, boolean painting); void roundOver(MoveEnemy duelEnemy);  }
@Test public void testSurf() { SurfMover mover = newSurfMover(); MoveEnemy duelEnemy = newDuelEnemy(); Point2D.Double sourceLocation1 = newLocation(700, 500); Point2D.Double targetLocation1 = newLocation(200, 150); Wave wave1 = duelEnemy.newMoveWave(sourceLocation1, targetLocation1, DiaUtils.absoluteBearing(sourceLocation1, targetLocation1), 1, 50L, 1.95, 100.0, Math.PI / 2, 8.0, 1, 0, 50, 150, 250, 9L, 3L); wave1.firingWave = true; Point2D.Double sourceLocation2 = newLocation(650, 530); Point2D.Double targetLocation2 = newLocation(240, 130); Wave wave2 = duelEnemy.newMoveWave(sourceLocation2, targetLocation2, DiaUtils.absoluteBearing(sourceLocation2, targetLocation2), 1, 65L, 1.95, 100.0, Math.PI / 2, 8.0, 1, 0, 50, 150, 250, 9L, 3L); wave2.firingWave = true; RobotState myRobotState = RobotState.newBuilder() .setLocation(targetLocation2) .setHeading(Math.PI / 2) .setVelocity(8.0) .setTime(67L) .build(); mover.surf(myRobotState, duelEnemy, wave1, 2, false); verifySomeRobotMovement(); }