-3

我正在编写一个在Robocode中运行的机器人。我的代码目前有效,我的坦克就像我希望它运行和移动一样运行。唯一的问题是它在战斗中多次撞墙,每次发生时我都会失去健康。

我尝试在 run() 方法中使用 getX() 和 getY() 将我的主题位置与我的网格的长度和宽度 getBattleFieldWidth() 和 getBattleFieldHeight() 进行比较,但这似乎不起作用。我还尝试将此代码放入我的 onScannedRobot() 方法中,但效果不佳。当我的对象从墙的每一侧接近 50 个单位时,我试图将我的对象的方向更改为与墙平行。然而,这还没有奏效。我也尝试做同样的事情,但改变了我的主题方向,但这也不起作用。我在 run() 和 onScannedRobot() 方法中都尝试了这一切,但还没有成功。

我尝试使用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拥抱(西蒙顿),但尚未占上风。

我正在使用 Robocode 版本 1.7.3.6 来运行此代码。

如何在我的代码中添加墙壁避免,或者最好是墙壁平滑?这是我的代码:

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;
        }         
    }
}
4

1 回答 1

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.)

于 2014-05-20T13:19:56.693 回答