@Override public List<Command> makeStrategy() { List<Command> commands = new ArrayList<Command>(); double power = 1; for (int i = 0; i < canShoot.length; i++) { if (currentSituation.myPlayersDetail()[canShoot[i]].getPower() < power) { power = currentSituation.myPlayersDetail()[canShoot[i]].getPower(); } } if (isShootSituation(power)) { double maxVertAngle = Constants.ANGULO_VERTICAL_MAX * Math.PI / 180; double angleVert; double angle = currentSituation .ballPosition() .angle(Constants.posteDerArcoSup.movePosition(-Constants.RADIO_BALON, 0)); angle = Math.min( angle + 0.5 * Constants.getErrorAngular(1.0) / 2 * Math.PI, currentSituation.ballPosition().angle(Constants.centroArcoSup)); double maxAngle = currentSituation .ballPosition() .angle(Constants.posteIzqArcoSup.movePosition(Constants.RADIO_BALON, 0)); maxAngle = Math.max( maxAngle - 0.5 * Constants.getErrorAngular(1.0) / 2 * Math.PI, currentSituation.ballPosition().angle(Constants.centroArcoSup)); ShootInfo shoot = new ShootInfo(); while (angle <= maxAngle) { angleVert = 0; while (angleVert <= maxVertAngle) { shoot = compareShoot(shoot, evaluateShoot(power, angle, angleVert)); angleVert += Math.PI / 180; } angle += Math.PI / 180; } for (int player : canShoot) { commands.add( new CommandHitBall( player, shoot.angle * 180 / Math.PI, 1, shoot.angleVert * 180 / Math.PI)); } } return commands; }
private ShootInfo evaluateShoot(double power, double angle, double angleVert) { TrajectoryMasia trajectory = new TrajectoryMasia( currentSituation.ballPosition(), Constants.getVelocidadRemate(power), angle, angleVert); double fitness = 0, f; for (int i = 0; i < trajectory.length; i++) { if (i == 0) { f = calculateFitness( trajectory.positions[i], trajectory.z[i], i + 1, currentSituation.ballPosition(), 0); } else { f = calculateFitness( trajectory.positions[i], trajectory.z[i], i + 1, trajectory.positions[i - 1], trajectory.z[i - 1]); } fitness += f; if (f > 1 || f == -1) { break; } } return new ShootInfo(angle, angleVert, fitness); }
private boolean isShootSituation(double power) { double factor = Math.abs(Math.sin(currentSituation.ballPosition().angle(Constants.centroArcoSup))); factor = 1 - (1 - factor) * (1 - factor); return currentSituation.ballPosition().distance(Constants.centroArcoSup) <= THRESHOLD * factor * Constants.getVelocidadRemate(power) / Constants.REMATE_VELOCIDAD_MAX; }