分享
 
 
 

Robocode高手的秘诀:因数避墙法

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

设计出一种算法,使您的机器人不会被困在角落里或者过多的偏离想要的移动方向,而且不会靠近墙,这是件很困难的事。因数避墙法是一种简单的解决办法。在这篇小技巧中,David McCoy 将向您展示如何实现这项方便的技术。

我们只要对在 Tracking your opponents' movement 中做的机器人加以补充,就能将因数避墙法添加到现有的或讨厌的移动算法中。这种方法将预想的方向和根据机器人和墙之间距离远近确定的安全方向作为因数试图找到最可能的方向。

添加做常见数学计算的辅助方法

我们先要给机器人添加常见数学算法使用的一些辅助方法。

calculateBearingToXYRadians() 方法使用 java.lang.Math 中的 atan2() 方法来计算从 sourceX,sourceY 到 targetX,targetY 的绝对方位,然后再把这个值转化为相对于 sourceHeading 的相对方位。

我们还需要 normalizeAbsoluteAngleRadians() 方法和 normalizeRelativeAngleRadians() 方法。

清单 1. 数学辅助方法

private static final double DOUBLE_PI = (Math.PI * 2);

private static final double HALF_PI = (Math.PI / 2);

public double calculateBearingToXYRadians(double sourceX, double sourceY,

double sourceHeading, double targetX, double targetY) {

return normalizeRelativeAngleRadians(

Math.atan2((targetX - sourceX), (targetY - sourceY)) -

sourceHeading);

}

public double normalizeAbsoluteAngleRadians(double angle) {

if (angle

return (DOUBLE_PI + (angle % DOUBLE_PI));

} else {

return (angle % DOUBLE_PI);

}

}

public static double normalizeRelativeAngleRadians(double angle) {

double trimmedAngle = (angle % DOUBLE_PI);

if (trimmedAngle Math.PI) {

return -(Math.PI - (trimmedAngle % Math.PI));

} else if (trimmedAngle

return (Math.PI + (trimmedAngle % Math.PI));

} else {

return trimmedAngle;

}

}

使 AdvancedRobot 扩展到有倒行功能

接着,为了以相反方向导航,我们需要用一些辅助方法把 AdvancedRobot 类的功能扩展到允许倒行操作:

getRelativeHeading() 方法将应付正确计算相对于机器人当前的方向的相对方向产生的额外开销。

reverseDirection() 非常简单。它负责 direction 实例变量的开关和使机器人掉头。请注意,由于减速需要时间,依据机器人的速度,在掉过头来之前最多会沿原来的方向再走 4 格。

setAhead() 和 setBack() 方法将覆盖 AdvancedRobot 类中的同名方法。这两个方法会设置机器人对于目前方向的相对速度,必要的时候,还会调整 direction 实例变量。我们这么做的目的是要确保相对操作都与机器人当前的移动方向有关。

setTurnLeftRadiansOptimal() 和 setTurnRightRadiansOptimal() 方法使机器人的方向转过的角度超过 (Math.PI / 2)。您会希望这个方法和 adjustHeadingForWalls 方法(我们将在后面讨论)一起使用。

注:我没有使用 getter 和 setter 方法,而是直接存取 direction 实例变量。尽管通常这并非良好的编程习惯,但为了加快数据存取,在我的机器人代码中我一直都是直接存取的。

清单 2. 机器人辅助方法

public double getRelativeHeadingRadians() {

double relativeHeading = getHeadingRadians();

if (direction

relativeHeading =

normalizeAbsoluteAngleRadians(relativeHeading + Math.PI);

}

return relativeHeading;

}

public void reverseDirection() {

double distance = (getDistanceRemaining() * direction);

direction *= -1;

setAhead(distance);

}

public void setAhead(double distance) {

double relativeDistance = (distance * direction);

super.setAhead(relativeDistance);

if (distance

direction *= -1;

}

}

public void setBack(double distance) {

double relativeDistance = (distance * direction);

super.setBack(relativeDistance);

if (distance 0) {

direction *= -1;

}

}

public void setTurnLeftRadiansOptimal(double angle) {

double turn = normalizeRelativeAngleRadians(angle);

if (Math.abs(turn) HALF_PI) {

reverseDirection();

if (turn

turn = (HALF_PI + (turn % HALF_PI));

} else if (turn 0) {

turn = -(HALF_PI - (turn % HALF_PI));

}

}

setTurnLeftRadians(turn);

}

public void setTurnRightRadiansOptimal(double angle) {

double turn = normalizeRelativeAngleRadians(angle);

if (Math.abs(turn) HALF_PI) {

reverseDirection();

if (turn

turn = (HALF_PI + (turn % HALF_PI));

} else if (turn 0) {

turn = -(HALF_PI - (turn % HALF_PI));

}

}

setTurnRightRadians(turn);

}

添加因数避墙法

我们需要添加的最后一个方法是 adjustHeadingForWalls() 方法。

这个方法的前面一半根据机器人和墙的靠近程度选择安全的 x 和 y 的位置(机器人当前的 x 或 y 位置,或者如果机器人靠近墙,则就是中心点)。方法的后面一半则计算距离“安全点”的方位,并把这个方位和依机器人离墙远近得到的预想方向都作为因数考虑在内。

可以使用 WALL_AVOID_INTERVAL 和 WALL_AVOID_FACTORS 常量来调整机器人对墙的担忧程度。

清单 3. 避墙法方法

private static final double WALL_AVOID_INTERVAL = 10;

private static final double WALL_AVOID_FACTORS = 20;

private static final double WALL_AVOID_DISTANCE =

(WALL_AVOID_INTERVAL * WALL_AVOID_FACTORS);

private double adjustHeadingForWalls(double heading) {

double fieldHeight = getBattleFieldHeight();

double fieldWidth = getBattleFieldWidth();

double centerX = (fieldWidth / 2);

double centerY = (fieldHeight / 2);

double currentHeading = getRelativeHeadingRadians();

double x = getX();

double y = getY();

boolean nearWall = false;

double desiredX;

double desiredY;

// If we are too close to a wall, calculate a course toward

// the center of the battlefield.

if ((y

((fieldHeight - y)

desiredY = centerY;

nearWall = true;

} else {

desiredY = y;

}

if ((x

((fieldWidth - x)

desiredX = centerX;

nearWall = true;

} else {

desiredX = x;

}

// Determine the safe heading and factor it in with the desired

// heading if the bot is near a wall

if (nearWall) {

double desiredBearing =

calculateBearingToXYRadians(x,

y,

currentHeading,

desiredX,

desiredY);

double distanceToWall = Math.min(

Math.min(x, (fieldWidth - x)),

Math.min(y, (fieldHeight - y)));

int wallFactor =

(int)Math.min((distanceToWall / WALL_AVOID_INTERVAL),

WALL_AVOID_FACTORS);

return ((((WALL_AVOID_FACTORS - wallFactor) * desiredBearing) +

(wallFactor * heading)) / WALL_AVOID_FACTORS);

} else {

return heading;

}

}

汇总

其余的工作很容易。我们可以使用目前的导航算法,将得出的结果送入 adjustHeadingForWalls() 方法来避开墙。

为了保持简单,示例机器人(请参阅参考资料下载添加这一技术所需的源代码)要求方向改变为零,从而试着沿直线移动。

清单 4. 避墙法方法

public void run() {

while(true) {

setTurnRightRadiansOptimal(adjustHeadingForWalls(0));

setAhead(100);

execute();

}

}

关于它就是这样了。简单,但有效。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有