• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

pedrotuga

Tutorial: manter outro robot na mira

7 mensagens neste tópico

Ora bem, isto acho que está nas FAQs, mas para principiantes pode ser pouco útil por si só pois trancar só não serve para nada e para alem disso pode nao ser boa estrategia focar o primeiro robot que aparecer e depois nunca mais o largar, se ele estiver longe e nao tivermos o trageting apropriado pode ser um desperdicio de tiros.

ora bem...

na nossa função onScannedRobot, que é chamada cada vez que o nosso radar detecta um robot podemos trancar um robot com o seguinte código:

double gunTurnAmt = normalRelativeAngle(e.getBearing() + (getHeading() - getRadarHeading()));
            setTurnGunRight(gunTurnAmt);
            

admitindo que e é o evento gerado pelo robot que o radar detectou e olhando para as documentação das funcoes usadas...

basicamente estamos dar ordem para rodar o canhão segundo:

o angulo da direcção do nosso robot 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

angulo do robot que acabámos de 'micar' em relação à direcção para onde o nosso robot está virado

a chamada da função normalRelativeAngle serve para normalizar o angulo, evitando assim que a arma vá dar a volta ao bilhar grande. Atenção, para isto funcionar, têm que definir essa função na classe do vosso robot. Encontra o seu código neste tópico:

http://www.portugal-a-programar.pt/index.php?showtopic=11393

Basicamente, após um turno, ou após a execução do que quer que seja que o robot está a executar, a arma do nosso robot vai rodar de forma a que aponte para o sitio onde vimos um robot da ultima vez. como isto é executado cada vez que encontramos um robot... enquanto não perdermos o robot inimigo da mira a nossa arma segue-o sempre.

Há que ter em atenção que este método usa a rotação do canhao para seguir o robot enimigo. Podiamos usar antes o radar que se move mais rapido e por isso não deixa escapar o enimigo tão facilmente. A razão pela qual usei o canão foi a simplicidade: desta forma o canhão está sempre pronto a disparar sem qualquer ajuste pois uma vez detectado o enimigo está o canhão virado para lá... FIRE!

Este método facilita o targetting mas tem uma desvantagem: se nunca deixarmos um robot escapar, o nosso robot pode realizar todos os seus movimentos e ficar apenas a focado em manter outro robot na mira. Acaba por ficar parado, e isso é meio caminho andado para levar um chuvada de chumbo. Por isso, é recomendado, após algum tempo a 'micar' um robot esquecer esse robot e rodar o canhão para outro lado.

Uma boa forma de evitar isso é usando um computador, ao fim de alguns scans deixamos aquele robot e vamos aprocura de outros:

Então.. no vosso onScannedRobot fica isto:

if(i%teimosia==0){
     turnGunRight(180); // voramo-nos para o outro lado
}
else{
    double gunTurnAmt = normalRelativeAngle(e.getBearing() + (getHeading() - getRadarHeading()));
    setTurnGunRight(gunTurnAmt);
}
i++;

e no inicio da vossa classe:

static int i=0;
static int teimosia=20; //ajustar a gosto

A variavel teimosia pode ser ajustada, quanto mais alto for o valor mais obcecado fica o nosso robot em relação aos outros robots que encontra.

Para ver esta tecnica em acção podem compilar um pequeno robot que eu escrevi para o efeito:

http://pastebin.com/f2c85a1f9

Não fiquem admirados por ele não disparar, é mesmo só para mostrar como manter outro robot na mira.

DICA: vao às opções do vosso robocode e ponham feixes de radar visiveis para ver melhor.

EDIT: o meu computador arrasta-se com o netbeans, robocode e um screen recorder, já testei dois... :S Se alguem quiser pode fazer um video com isto.

Qualquer reparo ou sugestão respondam a esta thread.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pessoal, como prometido aí está um tutorial acabado! Em portugues!

Faltam alguns pequenos ajustes e o video para todos perceberm melhor. Espero que isto incentive novos jogadores. Bora tudo construir máquinas infernais.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim senhor, bons tutoriais os que apresentas-te aqui :thumbsup: Já deu para ganhar umas ideias :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ainda não testei, e posso estar a pensar isso mal, mas ao colocares esta linha:

static int i=0;

Todas as instâncias deste robô irão partilhar a variável e o seu valor, quando um alterar o valor, todos vêm essa alteração. Será que isso é o pretendido?

Isto é, não me parece que haja problema, mas não creio que está correcto. Uma variável de controlo não deveria ser de classe, se ela pretende controlar o estado de um objecto tem de ser variável de instânica, senão controla o estado de todos os objectos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim, essa variavel é para ser vista em toda a classe para evitar que o robot fique "obcecado" noutro robot.

Não é o método mais elegante e na verdade não é uma boa prática, mas é a mais simples de perceber.

Já agora... vou mudar o valor da variavel teimosia, 5 é demasiado pequeno, não dá para ver o efeito.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Sim, essa variavel é para ser vista em toda a classe para evitar que o robot fique "obcecado" noutro robot.

Eu quero dizer todas as instâncias da mesma classe, isto é, se colocares dois robôs iguais na arena os dois vão ter a variável com o mesmo valor. Se o robô A tem a variável a 5 e executar o código para incrementar, o robô B vai ficar com a variável automáticamente a 6, se o robô B executar o código depois do A então a variável pode ser incrementada dois valores erradamente.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu quero dizer todas as instâncias da mesma classe, isto é, se colocares dois robôs iguais na arena os dois vão ter a variável com o mesmo valor. Se o robô A tem a variável a 5 e executar o código para incrementar, o robô B vai ficar com a variável automáticamente a 6, se o robô B executar o código depois do A então a variável pode ser incrementada dois valores erradamente.

mmm.. estou a ver, mas acho que esse problema não é assim tão grave quanto isso, se usarmos iniciais unicas como mandam as regras não há perigo de colisões de nomes. Mas ya, para testes é gajo para ter interferencia, é a unica situação onde estou a ver esse problema.

Mas acho que isso não tem grande volta a dar-lhe, por isso é que os robots têm que ter nome diferente..

Mas a titulo de curiosidade... como se contorna um problema destes em que se pretende manter varias instancias da mesma classe e que se necessite de aceder a determinada variavel em qualquer parte da classe?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora