Robocode  编写机器人 三

本文探讨了一种智能机器人策略,通过随机移动、圆周运动和避免碰撞的技巧来延长生命,直至敌方能量耗尽。策略包括周期性的随机移动、以敌人为圆心的圆周运动和巧妙的路径规划以避免碰撞。
我有个更大胆的假设:因为现在我的Bot命中率还不高,那么如果我的Bot一直不开火,只是躲避对方的子弹的话,能不能拖到对方的能量为0呢?确实存在一点问题。对方子弹一发射,我的Bot就移动,并且这个移动是规律的来回移动。如果移动距离短了,就可能在回来的时候撞到对方的子弹;如果移动距离长了,就等于做一个直线运动,对方很容易计算得到Bot的运动轨迹。还有一个问题,躲避的时候很有可能撞到墙上……(撞墙是要减energy的:)

针对以上的问题,我另写了一个Bot。代码如下:
import robocode.*;
public class HanicBot extends AdvancedRobot{
private double eDist; //对方的距离
private double move; //移动的距离
private double radarMove = 45; //雷达移动的角度
private double dFirePower; //火力

public void run() {
eDist = 300;
while(true){
//每过一个周期,运动随机的距离
double period = 4*((int)(eDist/80)); //周期;敌人越接近,周期越短,移动越频繁
//周期开始,则移动
if(getTime()%period == 0){
move = (Math.random()*2-1)*(period*8 - 25);
setAhead(move + ((move >= 0) ? 25: -25));
}
//避免撞墙
double heading = getHeadingRadians(); //取得bot方向的弧度数
double x = getX() + move*Math.sin(heading); //移动move后将要达到的x坐标
double y = getY() + move*Math.cos(heading); //移动move后将要达到的y坐标
double dWidth = getBattleFieldWidth(); //战场的宽度
double dHeight = getBattleFieldHeight(); //战场的长度
//当(x,y)超过指定的范围,则反向移动move
if(x < 30 || x > dWidth-30 || y < 30 || y > dHeight-30){
setBack(move);
}
turnRadarLeft(radarMove); //转动雷达
}
}//end run()

public void onScannedRobot(ScannedRobotEvent e) {
eDist = e.getDistance(); //取得对方距离
radarMove = -radarMove; //设置雷达
double eBearing = e.getBearingRadians(); //取得和对方相对角度的弧度数
//将bot转动相对的角度,以后bot的运动将是以对方为圆心的圆周运动
setTurnLeftRadians(Math.PI/2 - eBearing);
//转动炮管指向对方
setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(
getHeadingRadians() + eBearing - getGunHeadingRadians()));
//根据对方距离射击
dFirePower = 400/eDist;
if (dFirePower > 3){
dFirePower = 3;
}
fire(dFirePower);
}

首先,为了迷惑对方,不让对方容易的得到Bot的移动规律,Bot就要在一定的时间内做出随机的运动,这个很容易办到。并且,我给Bot的运动改变时间规定了周期。这个周期随离对方的距离改变,敌人越接近,周期越短,移动越频繁。
double period = 4*((int)(eDist/80));
if(getTime()%period == 0){
move = (Math.random()*2-1)*(period*8 - 25);
setAhead(move + ((move >= 0) ? 25: -25));
其次,Bot的运动不是呈直线的。而是以对方为圆心的圆周运动。
setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle) getHeadingRadians() + eBearing - getGunHeadingRadians())};
最后是如何避免撞墙。这里要用到点三角函数! 原理就是,计算Bot一次运动后将要达到的坐标是不是位于规定的危险区域。如果是,则立即反方向运动。
double heading = getHeadingRadians();
double x = getX() + move*Math.sin(heading);
double y = getY() + move*Math.cos(heading);
double dWidth = getBattleFieldWidth();
double dHeight = getBattleFieldHeight();
if(x < 30 || x > dWidth-30 || y < 30 || y > dHeight-30){
setBack(move);
}
package ms; import robocode.*; import java.util.*; //******************************************************************************************/ // GoodBot: determine, if a bot is a bastart or not // // needed: public void run() // GoodBot.Reset(); // public void onRobotDeath(RobotDeathEvent e) // GoodBot.BotDeath(e.getName(), this); // // example: public void onScannedRobot(ScannedRobotEvent e) // if (GoodBot.badBot(e.getName(), this)) //******************************************************************************************/ class GoodBot { static private Hashtable Bots = new Hashtable(); static private int GoodBots1 = 1; static private int GoodBots2 = 0; static private String bot; static public int KilledGoodBots1 = 0; static public int KilledGoodBots2 = 0; //******************************************************************************************/ // BadBot: is it a bad bot? //******************************************************************************************/ public static boolean badBot(String Name, AdvancedRobot in_this) { bot = (String)Bots.get(Name); if (bot == null) classBot(Name, in_this); int others = in_this.getOthers(); if ( (bot.compareTo("1") == 0) && (others >= GoodBots1 - KilledGoodBots1) ) return false; else if ( (bot.compareTo("2") == 0) && (others >= GoodBots1 - KilledGoodBots1 + GoodBots2 - KilledGoodBots2) ) return false; else return true; } public static void BotDeath(String Name, AdvancedRobot in_this) { bot = (String)Bots.get(Name); if (bot == null) classBot(Name, in_this); if ( bot.compareTo("1") == 0 ) KilledGoodBots1++; else if ( bot.compareTo("2") == 0 ) KilledGoodBots2++; } public static void Reset() { KilledGoodBots1 = 0; KilledGoodBots2 = 0; } private static void classBot(String Name, AdvancedRobot in_this) { int M_GoodBots = GoodBots1; String Gegnertyp = botTyp(Name); String Mytyp = botTyp(in_this.getName()); if (Gegnertyp.compareTo(Mytyp) == 0) { bot = "1"; if (GoodBots1 > M_GoodBots) in_this.out.println("I've found " + (GoodBots1 - 1) + " more " + Mytyp + "-Bot(s)."); } else { GoodBots1 = M_GoodBots; String Gegnerpack = botTyp2(Name); String Mypack = botTyp2(in_this.getName()); if (Gegnerpack.compareTo(Mypack) == 0) { bot = "2"; GoodBots2++; in_this.out.println("I've found " + (GoodBots2) + " more " + Mypack + "-Bot(s)."); } else bot = "0"; } Bots.put(Name, new String(bot)); } private static String botTyp(String BotName) { int k=BotName.indexOf("("); if (k != -1) { int Nr=Integer.parseInt(BotName.substring(k+1, BotName.indexOf(")")),10); if (GoodBots1 < Nr) GoodBots1 = Nr; return BotName.substring(0, k-1); } else return BotName; } private static String botTyp2(String BotName) { int k=BotName.indexOf("."); if (k != -1) { return BotName.substring(0, k); } else return BotName; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值