Manter Outro Robô na Mira
Neste tutorial vamos ver como podemos manter sob a nossa mira um robô inimigo. Embora focarmos apenas um inimigo, dos vários que certamente existirão na arena, possa complicar a nossa sobrevivência, é mesmo assim, um bom exercício e pode ser usado como parte de uma estratégia de combate.
Para detectar e manter sob mira um determinado robô, iremos usar a função onScannedRobot
, e implementar código de modo a sabermos sempre onde anda o nosso inimigo
double gunTurnAmt = normalRelativeAngle(e.getBearing() + (getHeading() - getRadarHeading()));
setTurnGunRight(gunTurnAmt);
De forma simples, estamos a dar uma ordem de modo a que o canhão rode segundo: o ângulo da direcção do nosso robô em relação ao norte, menos o ângulo do nosso radar (é o mesmo do canhão) em relação a direcção para onde estamos virados, mais o ângulo do robô que acabámos de detectar, em relação à direcção para onde o nosso robô está virado.
A chamada do método normalRelativeAngle
serve para normalizar o ângulo, evitando assim que a arma vá dar a volta ao bilhar grande. Essa função é introduzida no tutorial normalizar, e terá de ser adicionada ao robô para que o código acima funcione.
Após um turno, ou após a execução das tarefas que o robô tenha para fazer, a arma do nosso robô vai rodar de forma a que aponte para o sítio onde vimos um inimigo pela última vez. Como isto é executado cada vez que encontramos um robô, enquanto não perdermos o inimigo da mira a nossa arma segue-o sempre.
É necessário ter em atenção que este método usa a rotação do canhão para seguir o robô inimigo, podíamos usar antes o radar que se move a uma velocidade maior e dessa forma não deixa escapar o inimigo tão facilmente, mas usar o canhão é mais simples e assim está sempre pronto a disparar.
Este método facilita a questão de apontar, mas tem uma desvantagem: se nunca deixarmos um inimigo escapar, o nosso robô pode realizar todos os seus movimentos e ficar apenas focado em manter outro robô na mira. Acaba por ficar parado, e isso é meio caminho andado para levar uma chuva de chumbo. Por isso, é recomendado, após algum tempo a monitorizar um robô, esqueçamos esse inimigo e rodemos o canhão para outro lado.
Uma boa forma de evitar isso é usando um computador, ao fim de algumas passagens de radar deixamos aquele robô e vamos à procura de outros.
Alteramos o nosso método onScannedRobot
.
if(i % teimosia == 0){
turnGunRight(180); // virar para outro lado
} else {
double gunTurnAmt = normalRelativeAngle(e.getBearing() + (getHeading() - getRadarHeading()));
setTurnGunRight(gunTurnAmt);
}
i++;
E no início da classe:
private int i = 0;
private int teimosia = 20; //ajustar a gosto
A variável teimosia pode ser ajustada, quanto mais alto for o valor mais obcecado fica o nosso robô em relação aos outros robôs que encontra.
Para ver esta técnica em acção podem compilar um pequeno robô seguinte1:
import robocode.*;
import robocode.util.*;
import java.awt.Color;
public class TutorialBot extends AdvancedRobot{
int shots = 0;
int a = 0;
public void run() {
//definir algumas cores
setBodyColor(new Color(200, 200, 30));
setGunColor(new Color(45, 100, 0));
setRadarColor(new Color(0, 255, 100));
setBulletColor(new Color(255, 255, 100));
setScanColor(new Color(0, 255, 0));
while (true) {
turnGunLeft(10);
}
}
public void onScannedRobot(ScannedRobotEvent e) {
if (a % 25 == 0 ) {
turnGunLeft(180);
} else {
double gunTurnAmt = normalRelativeAngle(e.getBearing() + (getHeading() - getRadarHeading()));
setTurnGunRight(gunTurnAmt);
a++;
//System.out.print("n==========================");
//System.out.print("nradar heading:");
//System.out.print(getRadarHeading());
//System.out.print("nenemy angle:");
//System.out.print(e.getBearing());
//System.out.print("nremain angle:");
//System.out.print(getRadarHeading()-e.getBearing());
}
}
public double normalRelativeAngle(double angle) {
if (angle > -180 && angle <= 180) {
return angle;
}
double fixedAngle = angle;
while (fixedAngle <= -180) {
fixedAngle += 360;
}
while (fixedAngle > 180) {
fixedAngle -= 360;
}
return fixedAngle;
}
}
Não fiquem admirados por ele não disparar, é mesmo só para mostrar como manter outro robô na mira. Para verem melhor podem activar a opção que permite mostrar os feixes do radar, essa opção está disponível no painel de opções do Robocode.