What is the function to see the tank distance to the wall in the robocode?

Asked

Viewed 1,142 times

2

I’m trying to implement on robocode sourcecode (for those who don’t know, follow the link: http://robocode.sourceforge.net/) a means to make the tank continue walking and, from a certain distance from the wall, try to return.

For now that’s the code I tried, but I don’t know how to detect the distance to the walls:

package towerbot;  
import robocode.`*`;  
import java.awt.`*`;  
public class Towerbot extends Robot  
{  
    boolean movingforward;  
    public void run() {  
        setBodyColor(new Color(0,200,0));  
        while(true) {  
            setAhead(50);  
            setAhead(100);  
        }  
    }  
    public void onScannedRobot(ScannedRobotEvent e) {  
    turnGunRight(getHeading() - getGunHeading() + e.getBearing());  
    fire(1);  
    }  
    public void onHitByBullet(HitByBulletEvent e) {  

    }  
    public void onHitWall(HitWallEvent e) {  

    }   
}  
  • Study material here: read the questions tag [tag:artificial intelligence]. Some other useful material (in English) here: https://game-ai.zeef.com In any case, this site is not a forum. If you haven’t yet, please do the [tour] and read [Ask]. I love Robocode, but your question needs to be more objective. What have you tried to do? Edit the question to post the code snippet you already have and explain how you tried to achieve what you want.

  • If on the other hand your doubt is essentially what is in the title (which function to detect the distance? or how to calculate the distance to a target? ), edit the question and make the body of the question match the title (hence I withdraw my vote to close as broad). :)

  • I am trying to implement in the sourcecode robocode (for those who do not know, follow the link: http://robocode.sourceforge.net/) a means to make the tank continue walking and, from a certain distance from the wall, try to return. How can I implement this?

  • "I’m trying to implement..." -> what have you done? I repeat: post the excerpt of your code in which you have tried to implement something in this sense, because it will make it easier for us to understand exactly where is your difficulty.

1 answer

6

Well, if your need is just to calculate the distance to the walls, here’s an example of code that does that:

package towerbot;
import robocode.*;
import java.awt.*;
import java.awt.geom.*;

public class Towerbot extends robocode.Robot
{
    boolean movingforward;

    Point2D direcao;  // Vetor normalizado com a direção de movimento do tanque
    Point2D canto;    // Vetor do tanque até o canto mais próximo a que ele se aproxima
    double distancia; // Distância até as paredes

    final double limite = 80; // Limite utilizado para troca de direção

    public void run() {  
        setBodyColor(new Color(0,200,0));  
        while(true) {  
            ahead(5);
            calculaDistancia();

            if(distancia <= limite)
                turnLeft(180);
        }  
    }  

    public void calculaDistancia() {

        // Pega a altura e largura do campo de batalha e posição x,y do tanque
        double h = getBattleFieldHeight(); // Altura
        double w = getBattleFieldWidth();  // Largura
        double x = getX();
        double y = getY();

        // Pega a direção em que o tank se move e a sua posição atual (x, y) no campo de batalha
        double ang = getHeading(); // O ângulo está em graus, variando entre 0 (apontando pra cima) e 359) no sentido horário

        // Calcula os vetor normal de direção do tanque
        double dx = Math.sin(Math.toRadians(ang));
        double dy = Math.cos(Math.toRadians(ang));
        direcao = new Point2D.Double(dx, dy);

        // Calcula o vetor do tanque em direção ao canto mais próximo da direção e sentido que ele segue
        dx = (direcao.getX() > 0) ? w - x : -x;
        dy = (direcao.getY() > 0) ? h - y : -y;
        canto = new Point2D.Double(dx, dy);

        // Calcula os angulos entre o vetor de direcao e os vetores dos os eixos x e y
        double angX = Math.acos(Math.abs(direcao.getX()));
        double angY = Math.acos(Math.abs(direcao.getY()));

        // A distância é o cateto adjascente do menor ângulo
        if(angY < angX)
            distancia = Math.abs(canto.getY() / Math.cos(angY));
        else
            distancia = Math.abs(canto.getX() / Math.cos(angX));
    }   

    public void onPaint(Graphics2D g) {
        // Desenha a linha até a parede em amarelo se maior do que o limite, e em vermelho se menor do que o limite
        if(distancia <= limite)
            g.setColor(java.awt.Color.RED);
        else
            g.setColor(java.awt.Color.YELLOW);
        g.drawLine((int) getX(), (int) getY(), (int) (getX() + (distancia * direcao.getX())), (int) (getY() + (distancia * direcao.getY())));

        // Desenha o valor da distância em branco
        g.setColor(java.awt.Color.WHITE);
        g.drawString("Distancia: " + distancia, 10, 10);

        // Desenha as componentes do vetor do canto tracejados em branco
        Stroke pontilhado = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{10}, 0);
        g.setStroke(pontilhado);
        g.setColor(java.awt.Color.WHITE);
        g.drawLine((int) getX(), (int) getY(), (int) (getX() + canto.getX()), (int) getY()); // Componente em X
        g.drawLine((int) getX(), (int) getY(), (int) getX(), (int) (getY() + canto.getY())); // Componente em Y
     }

    public void onScannedRobot(ScannedRobotEvent e) {  
        //turnGunRight(getHeading() - getGunHeading() + e.getBearing());  
        //fire(1);
    }  

    public void onHitByBullet(HitByBulletEvent e) {  

    }  

    public void onHitWall(HitWallEvent e) {  

    }   
}

The result is a robot with this behavior:

inserir a descrição da imagem aqui

Explaining the code:

Basically I use some geometric calculations (tried to do more didactically) to get the direction vector of the movement of the tank (from the angle that Robocode returns) and then calculate the components on the x and y axes (marked blank with dotted lines) and "project" the direction vector according to the lower angle side (basically, the distance is the hypotenuse played in the cosine formula).

The "decision mechanism" is very simple, and as you wanted: it reverses the sense of movement if the distance becomes less than an established limit.

Remarks:

  • Note that the plots are debug information, drawn in the method call onPaint and that needs to be enabled with the button "Paint" in your robot’s console window.
  • There are other better ways to make the robot avoid walls. I suggest reading the documentation, especially the examples like the Wall Smoothing (and its implementations).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.