Ir para o conteúdo
pedrotuga

Tutorial: manter outro robot na mira

Mensagens Recomendadas

pedrotuga    31
pedrotuga

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.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
pedrotuga    31
pedrotuga

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.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Knitter    101
Knitter

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.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
pedrotuga    31
pedrotuga

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.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Knitter    101
Knitter
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.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
pedrotuga    31
pedrotuga

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?

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


×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade