Robocode学习笔记(四)

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

  上一次我所提到的躲避方法,确实存在一点问题。对方子弹一发射,我的Bot就移动,并且这个移动是规律的来回移动。如果移动距离短了,就可能在回来的时候撞到对方的子弹;如果移动距离长了,就等于做一个直线运动,对方很容易计算得到Bot的运动轨迹。还有一个问题,躲避的时候很有可能撞到墙上……(撞墙是要减energy的:~()

  针对以上的问题,我另写了一个Bot。代码如下:

import Robocode.*;

public class HanicBot extends AdvancedRobot{  private double eDist; //对方的距离  private double move; //移动的距离  private double radarMove = 45; //雷达移动的角度  private double dFirePower;  //火力

  /**   * main func run()   */  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()

  /**   * 当检测到对方Bot,触发事件   * @param e   */  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);}

  今天就写到这,呵呵。

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值