雷达扫描效果

    技术2024-03-27  81

    Robocode成功的关键之一始终是掌握每个敌方机器人的最新信息。 要做到这一点,您必须以不会扫过更多战场的方式使用雷达。 例如,当您的机器人站在角落时,进行完整的360度扫掠是没有意义的。

    本技巧文章讨论了我在et.Predator中用于控制雷达的代码。 假定您的机器人是AdvancedRobot,并且您有一个Enemy类(一个包含ScannedRobotEvents信息的类)和一个EnemyMap类(一个敌人集合)。 我正在使用的EnemyMap扩展了HashMap ,但您也可以使用Hashtable或其他合适的类。

    Enemy类必须具有isUpdated()函数,该函数检查自信息最后一次更新以来的时间getTime()机器人的getTime()减去ScannedRobotEvent getTime() )是否低于某个限制。 我目前使用16作为限制。

    在机械手的初始化部分(在循环之前的run() )中,使用以下命令:

    addCustomEvent(new RadarTurnCompleteCondition(this)); setAdjustRadarForGunTurn(true); setTurnRadarRight(360);

    接下来,为自定义事件添加事件处理程序:

    public void onCustomEvent(CustomEvent e) { if (e.getCondition() instanceof RadarTurnCompleteCondition) sweep(); }

    您还应该getScannedRobotEvents()使用getScannedRobotEvents()以确保记录所有ScannedRobotEvents 。

    最后,添加清单1中的代码以控制雷达扫描。 请注意,该代码使用int sign(double n)方法,该方法返回数字n(-1或1)的符号。 它还使用normalRelativeAngle(double angle)将输入角度标准化为-180至180度之间的角度。

    清单1.雷达扫描方法
    private int radarDirection=1; private void sweep() { double maxBearingAbs=0, maxBearing=0; int scannedBots=0; Iterator iterator = theEnemyMap.values(). iterator(); while(iterator.hasNext()) { Enemy tmp = (Enemy)iterator.next(); if (tmp!=null && tmp.isUpdated()) { double bearing=normalRelativeAngle (getHeading() + tmp.getBearing() - getRadarHeading()); if (Math.abs(bearing)>maxBearingAbs) { maxBearingAbs=Math.abs(bearing); maxBearing=bearing; } scannedBots++; } } double radarTurn=180*radarDirection; if (scannedBots==getOthers()) radarTurn=maxBearing+sign(maxBearing)*22.5; setTurnRadarRight(radarTurn); radarDirection=sign(radarTurn); }

    函数sweep()确定其他机器人的轴承绝对值的最大值。 如果所有机器人都进行了更新,它将使雷达转向具有最大方位的敌人。 如果尚未更新某些机器人,则会将雷达设置为继续沿当前方向扫掠。

    请注意,我向扫描添加了22.5度,这是一个安全余量,因为自上次扫描以来机器人已经移动了。 选择22.5作为常数的动机是雷达每帧大约旋转45度。 通过不使用常数,可以计算与最大轴承的机器人之间的距离,并计算正确轴承可以具有的最大值,从而可以改进算法。


    翻译自: https://www.ibm.com/developerworks/java/library/j-radar/index.html

    相关资源:js实现地图上雷达探测效果
    Processed: 0.016, SQL: 12