标签:
package jiaqi;
import java.awt.geom.Point2D;
import robocode.AdvancedRobot;
import robocode.Rules;
import robocode.ScannedRobotEvent;
public class MyDemoRobot extends AdvancedRobot{
/**
* 扫描到敌人的时间
*/
private double time1 = 0;
private Enemy enemy = new Enemy();
private boolean discover = false;// 敌人是否被发现属性
private double heading = 0.0;
private double radarHeading = 0.0;
private double bPower = 3;
private double time = 0; // 子弹飞行时间
private double distance = 3000;// 敌人即将到达的位置的距离
@Override
public void onScannedRobot(ScannedRobotEvent e) {
discover = true;// 发现敌人
time1 = getTime();
// 初始化敌人
enemy.setBearing(e.getBearingRadians());
enemy.setSpeed(e.getVelocity());
enemy.setDistance(e.getDistance());
enemy.setHeading(e.getHeadingRadians());
time = distance / Rules.getBulletSpeed(bPower);
}
/**
* 打扮
*/
private void dressing() {
}
/**
* 车炮和雷达分离
*/
private void severance() {
setAdjustGunForRobotTurn(true);
setAdjustRadarForGunTurn(true);
}
/**
* 最简单的移动算法
*/
private void simpleMove() {
double increment = 0;
if (enemy.getBearing() > 0) {
increment = Math.PI / 2 - enemy.getBearing();
setTurnLeftRadians(increment);
} else {
increment = Math.PI / 2 + enemy.getBearing();
setTurnRightRadians(increment);
}
setAhead(1000);
}
/**
* 安全距离
*/
private double safDis = 100;
/**
* 移动
*/
private void movement() {
if (getDistanceRemaining() < 1) {
double nx = 0;
double ny = 0;
// 计算一个随机的安全的X,Y坐标
nx = Math.random() * (getBattleFieldWidth() - 2 * safDis) + safDis;
ny = Math.random() * (getBattleFieldHeight() - 2 * safDis) + safDis;
double headArg = 90 - Math.atan2(ny - getY(), nx - getX());// 计算我们车身要旋转的角度
headArg = getPA(headArg);
double dis = Point2D.distance(getX(), getY(), nx, ny);// 计算我们的机器人移动的距离
if (headArg - getHeadingRadians() > Math.PI / 2) {
setTurnRightRadians(headArg - getHeadingRadians() + Math.PI);
setAhead(-dis);
} else {
setTurnRightRadians(headArg - getHeadingRadians());
setAhead(dis);
}
}
}
/**
* 雷达锁定敌人
*/
private void doScan() {
// 判断是否扫描到敌人
if (discover) {
// 计算雷达旋转的角度
heading = this.getHeadingRadians();
radarHeading = this.getRadarHeadingRadians();
double temp = radarHeading - heading - enemy.getBearing();
// 处理异常角度
temp = correctAngle(temp);
temp *= 1.2;
// 设置机器人的雷达回扫
setTurnRadarLeftRadians(temp);
// 开始执行机器人运行的设置
}
}
/**
* 选择火力
*/
private double firePower() {
return bPower;
}
private double correctAngle(double scan) {
scan %= 2 * Math.PI;// 防止出现大于360度的角
if (scan > Math.PI) {
scan = -(2 * Math.PI - scan);// 计算出角度取负为了让雷达反方向旋转
}
if (scan < -Math.PI) {
scan = 2 * Math.PI + scan;
}
return scan;
}
/**
* 直接瞄准
*/
private double immidate() {
double increment = heading + enemy.getBearing()
- getGunHeadingRadians();
increment %= 2 * Math.PI;
increment = correctAngle(increment);
return increment;
}
/**
* 调炮
*/
private void gun() {
// double increment = immidate();
double increment = line();
setTurnGunRightRadians(increment);
}
/**
* 获得正角的方法
*
* @return
*/
private double getPA(double angle) {
angle %= 2 * Math.PI;
if (angle < 0) {
angle += 2 * Math.PI;
}
return angle;
}
/**
* 直线瞄准
*
* @return
*/
private double line() {
// 计算出敌人即将出现的坐标
// 1. 计算敌人目前的坐标
double ea = getPA(getHeadingRadians() + enemy.getBearing());// 敌人的所在方向角度
double ex = getX() + enemy.getDistance() * Math.sin(ea);// 敌人目前的X坐标
double ey = getY() + enemy.getDistance() * Math.cos(ea);// 敌人目前的Y坐标
// 2. 计算敌人即将运动距离
double s = 0;// 保存敌人运动距离
if (enemy.getSpeed() >= Rules.MAX_VELOCITY - 0.1) {
s = enemy.getSpeed() * time;
} else if (enemy.getSpeed() > 0.0) {
double as = (Math.pow(Rules.MAX_VELOCITY, 2) - Math.pow(
enemy.getSpeed(), 2))
/ 2 * Rules.ACCELERATION;// 加速运动的距离
double vs = (time - (Rules.MAX_VELOCITY - enemy.getSpeed())
/ Rules.ACCELERATION)
* Rules.MAX_VELOCITY;// 匀速运动的距离
s = as + vs;
} else {
s = 0.0;
}
// 3. 计算敌人即将出现的坐标
double nextx = ex + s * Math.sin(enemy.getHeading());
double nexty = ey + s * Math.cos(enemy.getHeading());
distance = Point2D.distance(getX(), getY(), nextx, nexty);
double t = Math.atan2(nexty - getY(), nextx - getX());// 计算敌人即将到达位置的角度
return correctAngle((Math.PI / 2 - t - getGunHeadingRadians())
% (2 * Math.PI));
}
public void run() {
// 第一步:要给机器人一身漂亮的行头,车身,炮和雷达及扫描弧要着上独特的颜色。
dressing();
// 第二步:要让机器人的车炮和雷达分离,互不影响。高级机器人都这样做。
severance();
// 让雷达先转一圈,以触发雷达扫描事件
// setTurnRadarLeft(400);
// execute();
while (true) {
if (!discover) {
setTurnRadarLeftRadians(Math.PI * 2.1);
execute();
} else {
// 第三步:要确定机器人如何移动的算法
movement();
// 第四步:要确定机器人如何选择火力的算法
double fire = firePower();
// 第五步:要确定机器人如何锁定其它机器人的算法
doScan();
// 第六步:要确定机器人如何计算角度并调整炮口瞄准敌人的算法
gun();
// if (getGunTurnRemaining() <= 0) {
// 开枪
setFire(fire);
execute();
// }
// 判断敌人是否丢失
loseTarget();
execute();
}
}
}
/**
* 判断是否丢掉敌人
*
*/
private void loseTarget() {
if ((getTime() - time1) >= 4)
discover = false;
}
}
======================================
package jiaqi;
public class Enemy {
private double bearing;//自己与敌人的夹角
private double distance;//与敌人的距离
private double heading;
private double velocity;
private double speed;
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getBearing() {
return bearing;
}
public void setBearing(double bearing) {
this.bearing = bearing;
}
public double getDistance() {
return distance;
}
public void setDistance(double distance) {
this.distance = distance;
}
public double getHeading() {
return heading;
}
public void setHeading(double heading) {
this.heading = heading;
}
public double getVelocity() {
return velocity;
}
public void setVelocity(double velocity) {
this.velocity = velocity;
}
}
标签:
原文地址:http://www.cnblogs.com/aicpcode/p/4292089.html