-3

I am programming a robot that runs in Robocode. My code currently works, and my tank runs just like I want it to run and move. The only problem is that it runs into the wall several times a battle and I lose health every time that occurs.

I have tried to compare my subject's position using getX() and getY() against the length and width of my grid, getBattleFieldWidth() and getBattleFieldHeight(), in the run() method however, that does not seem to work. I also tried putting this code in my onScannedRobot() method and that did not work as well. I have attempted to, as my subject approaches 50 units away form each side of the wall, to change the direction of my subject to being parallel to the wall. However, that has yet to work. I have also tried to do the same thing but reverse the direction of my subject, but that does not work either. I have tried this all in both the run() and onScannedRobot() methods and have yet to succeed.

I have attempted to use the algorithms described in the RoboWiki Wall Smoothing/Implementations page: Simple Iterative Wall Smoothing (by PEZ), Fast Wall Smoothing (by Voidious), Non-Iterative Wall Smoothing (by David Alves), and Non-Iterative Wall Hugging (by Simonton), and have yet to prevail.

I am using Robocode Version 1.7.3.6 to run this code.

How do I add wall avoidance, or preferably wall smoothing, to my code? Here is my code:

package stephen.tanks;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import robocode.*;
import robocode.util.Utils;


public class AimmaKickeraskTank extends AdvancedRobot {
    static int currentEnemyVelocity;
    static int aimingEnemyVelocity;
    double velocityToAimAt;
    boolean fired;
    Rectangle grid = new Rectangle(0, 0, 800, 600);
    double oldTime;
    int count;
    int averageCount;
    static double enemyVelocities[][] = new double[400][4];
    static double turn = 2;
    int turnDir = 1;
    int moveDir = 1;
    double oldEnemyHeading;
    double oldEnergy = 100;


    @Override
    public void run() {
        setBodyColor(Color.blue);
        setGunColor(Color.blue);
        setRadarColor(Color.black);
        setScanColor(Color.yellow);
        setAdjustGunForRobotTurn(true);
        setAdjustRadarForGunTurn(true);

        while (true) {
            turnRadarRightRadians(Double.POSITIVE_INFINITY);
        }
    }


    @Override
    public void onScannedRobot(ScannedRobotEvent e) {
        double absBearing = e.getBearingRadians() + getHeadingRadians();
        Graphics2D g = getGraphics();
        turn += 0.2 * Math.random();
        if (turn > 8) {
            turn = 2;
        }

        if(oldEnergy - e.getEnergy() <= 3 && oldEnergy - e.getEnergy() >= 0.1) {
            if (Math.random() > .5) {
                turnDir *= -1;
            }
            if(Math.random() > .8) {
                moveDir *= -1;
            }
        }

        setMaxTurnRate(turn);
        setMaxVelocity(12 - turn);
        setAhead(90 * moveDir);
        setTurnLeft(90 * turnDir);
        oldEnergy = e.getEnergy();

        if (e.getVelocity() < -2) {
            currentEnemyVelocity = 0;
        }
        else if (e.getVelocity() > 2) {
            currentEnemyVelocity = 1;
        }
        else if (e.getVelocity() <= 2 && e.getVelocity() >= -2) {
            if (currentEnemyVelocity == 0) {
                currentEnemyVelocity = 2;
            }
            else if (currentEnemyVelocity == 1) {
                    currentEnemyVelocity = 3;
            }
        }
        if (getTime() - oldTime > e.getDistance() / 12.8 && fired == true) {
            aimingEnemyVelocity=currentEnemyVelocity;
        }
        else {
            fired = false;
        }

        enemyVelocities[count][aimingEnemyVelocity] = e.getVelocity();
        count++;

        if(count==400) {
            count=0;
        }

        averageCount = 0;
        velocityToAimAt = 0;

        while(averageCount < 400) {
            velocityToAimAt += enemyVelocities[averageCount][currentEnemyVelocity];
            averageCount++;
        }

        velocityToAimAt /= 400;

        double bulletPower = Math.min(2.4, Math.min(e.getEnergy()/3.5, getEnergy()/9));
        double myX = getX();
        double myY = getY();
        double enemyX = getX() + e.getDistance() * Math.sin(absBearing);
        double enemyY = getY() + e.getDistance() * Math.cos(absBearing);
        double enemyHeading = e.getHeadingRadians();
        double enemyHeadingChange = enemyHeading - oldEnemyHeading;
        oldEnemyHeading = enemyHeading;
        double deltaTime = 0;
        double battleFieldHeight = getBattleFieldHeight();
        double battleFieldWidth = getBattleFieldWidth();
        double predictedX = enemyX, predictedY = enemyY;

        while ((++deltaTime) * (20.0 - 3.0 * bulletPower) < Point2D.Double.distance( myX, myY, predictedX, predictedY)) {      
            predictedX += Math.sin(enemyHeading) * velocityToAimAt;
            predictedY += Math.cos(enemyHeading) * velocityToAimAt;
            enemyHeading += enemyHeadingChange;
            g.setColor(Color.red);
            g.fillOval((int)predictedX - 2,(int)predictedY - 2, 4, 4);

            if (predictedX < 18.0 || predictedY < 18.0 || predictedX > battleFieldWidth - 18.0 || predictedY > battleFieldHeight - 18.0) {   
                predictedX = Math.min(Math.max(18.0, predictedX), battleFieldWidth - 18.0); 
                predictedY = Math.min(Math.max(18.0, predictedY), battleFieldHeight - 18.0);
                break;
            }
        }

        double theta = Utils.normalAbsoluteAngle(Math.atan2(predictedX - getX(), predictedY - getY()));
        setTurnRadarRightRadians(Utils.normalRelativeAngle(absBearing - getRadarHeadingRadians()) * 2);
        setTurnGunRightRadians(Utils.normalRelativeAngle(theta - getGunHeadingRadians()));

        if(getGunHeat() == 0) {
            fire(bulletPower);
            fired = true;
        }         
    }
}
Jason
  • 1,658
  • 3
  • 20
  • 51
Stephen3107
  • 13
  • 1
  • 3
  • What have you tried, where do you get stuck, is your code bugged, you need to ask a more specific question. – M. Mimpen May 20 '14 at 13:13
  • I think you should have a list of the coordinates of the walls and then check that against the position or coordinates of the subject that has to avoid the wall. When the difference in their positions is `<= 0` that's a collision right there. – Omoro May 20 '14 at 13:13
  • 2
    Step back from your code and work out a solution on paper (within the constraints of what your robot can do RIGHT NOW). Once you think you have a solution, check it ever, then pseudo-code, then code. – EyeOfTheHawks May 20 '14 at 13:13
  • This is wayyyy to vague of a question, what exactly is the *problem*. – DirkyJerky May 20 '14 at 13:19
  • What is your problem ? – Andrei May 20 '14 at 13:26
  • This question seems pretty clear to me, but that might be because I've previously played around with Robocode. I'll edit the question to add a link to a Robocode intro so it's more accessible to the general SO audience. – Conspicuous Compiler May 21 '14 at 17:24

1 Answers1

0

Detect when your robot will hit a wall soon, and alter your course (or drive backwards) if that's the case?

For detecting nearby walls, you might want to check your robots current position with getX(), getY(), compare this to the height and width of the arena getBattlefieldWidth(), getBattlefieldHeight().

To find out whether you are driving towards the wall, you can check getHeading() and the sign of getVelocity().

(If you want a more specific answer, try pointing out which aspect of the problem you are having trouble with.)

meriton
  • 68,356
  • 14
  • 108
  • 175