我正在编写一个在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;
}
}
}