获取当前帧的敌人的位置和自己的位置以及射击的角度,子弹的速度
每一帧获取一次
当有足够多的数据后,根据当前的位置和角度,获取之前最有可能打中地方的攻击方式。
Robocode 模式匹配和随机移动
波保存敌人的起始点、自己的起始点、与敌人的绝对夹角、敌人的距离、发现敌人的时间、射击角度、速度的水平分量、速度的垂直分量
“波”统计瞄准算法进行模式匹配
直线瞄准以及圆周瞄准算法都是全匹配算法
我们将拥有超级机器人“波”统计瞄准算法与直线瞄准和圆周瞄准算法的机器人进行比拼
//传播波的算法
package com.xalead.superrobot;
import java.awt.geom.Point2D;
import robocode.AdvancedRobot;
import robocode.Condition;
import robocode.Rules;
import robocode.util.Utils;
import com.xalead.superrobot.model.Battle;
public class Wave extends Condition{
//自己的起始点坐标
private Point2D.Double myStartPos = null;
//创建这个波时敌人的绝对夹角
private double absBearing = 0;
//发现敌人的时间
private double startTime;
//敌人的距离
private double dist;
//速度垂直分量
private double adSeg;
//速度的水平分量
private double velSeg;
//这个值只有当波碰到敌人时才能产生
private double angle;
//战场模型的引用
private Battle battle = null;
//执有机器人的引用
private WaveSurfing robot = null;
public Wave(){}
public Wave(Battle battle){
this.battle = battle;
robot = (WaveSurfing)battle.getRobot();
}
public Point2D.Double getMyStartPos() {
return myStartPos;
}
public void setMyStartPos(Point2D.Double myStartPos) {
this.myStartPos = myStartPos;
}
public double getAbsBearing() {
return absBearing;
}
public void setAbsBearing(double absBearing) {
this.absBearing = absBearing;
}
public double getStartTime() {
return startTime;
}
public void setStartTime(double startTime) {
this.startTime = startTime;
}
public double getDist() {
return dist;
}
public void setDist(double dist) {
this.dist = dist;
}
public double getAdSeg() {
return adSeg;
}
public void setAdSeg(double adSeg) {
this.adSeg = adSeg;
}
public double getVelSeg() {
return velSeg;
}
public void setVelSeg(double velSeg) {
this.velSeg = velSeg;
}
public double getAngle() {
return angle;
}
public void setAngle(double angle) {
this.angle = angle;
}
public Battle getBattle() {
return battle;
}
public void setBattle(Battle battle) {
this.battle = battle;
}
//传播波的算法
public boolean test() {
System.out.println(battle.getePos().getX() + ":" + battle.getePos().getY());
//判断当前波传播的距离是否和敌人目前所在位置的距离接近
if((robot.getTime() - this.getStartTime())
* Rules.getBulletSpeed(robot.BULLET_POWER) >= Point2D.distance(
battle.getePos().getX(),battle.getePos().getY(),
myStartPos.getX(),myStartPos.getY())){
this.angle =Utils.normalRelativeAngle(Utils.
normalAbsoluteAngle(Math.atan2(battle.getePos().getX()
- this.myStartPos.getX(),battle.getePos().getY()
- this.myStartPos.getY())) - this.absBearing );
battle.getFireAngle().add(this);
robot.removeCustomEvent(this);
}
return false;
}
}
//超级机器人 波统计瞄准算法
package com.xalead.superrobot;
import java.awt.geom.Point2D;
import com.xalead.superrobot.model.Battle;
import robocode.AdvancedRobot;
import robocode.ScannedRobotEvent;
import robocode.util.Utils;
public class WaveSurfing extends AdvancedRobot{
private Battle battle = null;
//子弹能量
public static double BULLET_POWER = 2;
public void run(){
battle = new Battle(this);
setAdjustGunForRobotTurn(true);
setAdjustRadarForGunTurn(true);
turnRadarRightRadians(Double.POSITIVE_INFINITY);
}
public void onScannedRobot(ScannedRobotEvent e){
//雷达锁定
setTurnRadarRightRadians(Utils.normalRelativeAngle((e.getBearingRadians() + getHeadingRadians() -getRadarHeadingRadians()))*2);
//更新敌人位置坐标
battle.update(e);
//创建波
battle.createWave(e);
movement();
//获得最佳匹配角并射击
setFire(e.getDistance()<100 ?3 : BULLET_POWER);
setTurnGunRightRadians(battle.getBestMatchFireAngle());
}
private double safDis = 100;
//移动算法
private void movement() {
if (getDistanceRemaining() < 1) {
double nx = 0;
double ny = 0;
nx = Math.random() * (getBattleFieldWidth() - 2 * safDis) + safDis;
ny = Math.random() * (getBattleFieldHeight() - 2 * safDis) + safDis;
double headArg = 90 - Math.atan2(ny - getY(), nx - getX());
headArg = Utils.normalAbsoluteAngle(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);
}
}
}
}
//战场要素
package com.xalead.superrobot.model;
import java.awt.geom.Point2D;
import java.awt.geom.Point2D.Double;
import com.xalead.superrobot.Wave;
import com.xalead.superrobot.util.ArrayList;
import com.xalead.superrobot.util.Iterator;
import robocode.AdvancedRobot;
import robocode.ScannedRobotEvent;
import robocode.util.Utils;
public class Battle {
private AdvancedRobot robot =null;
private double battleFieldWidth;
private double battleFieldHeight;
//保存射击角度的模式库
private ArrayList fireAngle = new ArrayList();
public Battle(){}
public Battle(AdvancedRobot robot) {
this.robot = robot;
this.battleFieldHeight = robot.getBattleFieldHeight();
this.battleFieldWidth = robot.getBattleFieldWidth();
}
public AdvancedRobot getRobot() {
return robot;
}
public void setRobot(AdvancedRobot robot) {
this.robot = robot;
}
public double getBattleFieldWidth() {
return battleFieldWidth;
}
public void setBattleFieldWidth(double battleFieldWidth) {
this.battleFieldWidth = battleFieldWidth;
}
public double getBattleFieldHeight() {
return battleFieldHeight;
}
public void setBattleFieldHeight(double battleFieldHeight) {
this.battleFieldHeight = battleFieldHeight;
}
//敌人最新的所在的位置
private Point2D.Double ePos = null;
/*
* 敌人速度的水平分量
* */
private double dist;//距离
//敌人速度的垂直分量
private double velSeg;
//敌人速度的水平分量
private double adSeg ;
private double absBearing;//敌人的所在方向的绝对夹角
public void update(ScannedRobotEvent e) {
absBearing = e.getBearingRadians();//夹角
dist = e.getDistance();//距离
compute(dist,absBearing += robot.getHeadingRadians());
velSeg = e.getVelocity() * Math.cos(e.getHeadingRadians() - absBearing);
adSeg = e.getVelocity() * Math.sin(e.getHeadingRadians() - absBearing);
}
public void createWave(ScannedRobotEvent e) {
Wave wave = new Wave(this);
//雷达锁定敌人
if(robot.getGunHeat() <= 0){
wave.setStartTime(robot.getTime());//记录创建波的时间
wave.setVelSeg(velSeg);//记录敌人速度的水平分量
wave.setAdSeg(adSeg);//记录敌人速度的垂直分量
wave.setMyStartPos(new Point2D.Double(robot.getX(),robot.getY()));//记录创建波时我们的起始位置
wave.setDist(dist);//敌人的距离
wave.setAbsBearing(absBearing);//敌人所在方向的绝对夹角
robot.addCustomEvent(wave);
}
}
/*
* 获得最佳匹配射击角
* */
public double getBestMatchFireAngle(){
double aim =0;
double distance;//存储欧几里德距离
//定义一个匹配,初始化成一个非常大的值
double maxMatch = java.lang.Double.POSITIVE_INFINITY;
Iterator iter = fireAngle.iterator();
while(iter.hasNext()){
Wave w = iter.next();
//计算欧几里德距离,匹配信号相似度
distance = Math.pow(velSeg - w.getVelSeg(),2)+Math.pow((adSeg - w.getAdSeg()),2)+Math.pow((w.getDist() - dist)/200,2);
if(distance < maxMatch){
maxMatch = distance;
aim = w.getAngle();
}
}
return Utils.normalRelativeAngle(absBearing - robot.getGunHeadingRadians() + aim);
}
/*计算敌人坐标位置
* dist 敌人的距离
* d 敌人方向的绝对角
* return 敌人的位置
* */
public Point2D.Double compute(double dist, double d) {
return this.ePos = new Point2D.Double(robot.getX() + dist * Math.sin(d),robot.getY() + dist *Math.cos(d));
}
public ArrayList getFireAngle() {
return fireAngle;
}
public void setFireAngle(ArrayList fireAngle) {
this.fireAngle = fireAngle;
}
public Point2D.Double getePos() {
return ePos;
}
public void setePos(Point2D.Double ePos) {
this.ePos = ePos;
}
}
//迭代器
package com.xalead.superrobot.util;
import com.xalead.superrobot.Wave;
public interface Iterator {
public boolean hasNext();
public Wave next();
}
//集合
package com.xalead.superrobot.util;
import com.xalead.superrobot.Wave;
public class ArrayList {
private Wave[] waves = new Wave[10];
private int size = 0;
public int size(){
return size;
}
public boolean add(Wave wave){
if(size < waves.length){
waves[size] = wave;
}
if(size >= waves.length){
Wave[] temp = new Wave[waves.length * 2];
for(int i=0; i<waves.length;i++){
temp[i]=waves[i];
}
temp[size] = wave;
waves = temp;
}
size++;
return true;
}
public boolean remove(Wave wave){
for(int i=0;i<size;i++){
if(waves[i] == wave){
for(int j =i;j<(size -1);j++){
waves[j] = waves[j+1];
}
waves[size - 1] =null;
size--;
return true;
}
}
return false;
}
public Iterator iterator(){
return new LIr();
}
private class LIr implements Iterator{
private int cursor = 0;
// public void offset(int offset){
// cursor = offset;
// }
public boolean hasNext(){
return cursor < size();
}
public Wave next(){
Wave w = waves[cursor];
if(w != null){
cursor++;
}
return w;
}
}
}
直线瞄准算法与超级机器人:
运行结果:
圆周瞄准算法与超级机器人:
运行界面:
运行结果:
由此可知,算法不同,机器人攻击能力不一样,所以全匹配性机器人直线瞄准和圆周瞄准机器人不能打过超级机器人“波”统计瞄准算法。