反重力引擎

    技术2024-03-21  87

    反重力运动是一种高度灵活的技术,通过允许您在战场上定义避免避开的特定点(称为重力点 ),可以帮助您欺骗模式分析机器人。 每个重力点都有自己的强度 。 通过沿x和y方向解析这种强度的分量,可以很好地避开所有敌方机器人。 (请参阅侧栏“ 反重力术语 ”以帮助理解本技巧中使用的术语。)

    本技巧的第一部分介绍了一种基本的反重力技术,而下一部分介绍了解决此基本代码固有的局限性的想法。

    反重力运动背后的数学

    反重力术语

    重力点:这些是Robocode战场上的点,您将它们定义为要排斥或吸引的区域。

    力:每个重力点都分配有力或强度 。 值越大,从产生力的角度看,您的机器人被吸引或排斥的越多。

    力的分量 :每个力都有一个分量在x方向(水平)上作用,一个分量在y方向(垂直)上作用。 45度角在x和y方向上具有相等的分量。 90度角完全在x方向上起作用,0度角完全在y方向上起作用。

    分解力:这是确定当多个力互相作用时产生的总力的过程。 例如,如果在x方向上有-200的力,在x方向上也有300的力,则产生的总力在x方向上是100。

    如果您具有三角学的实际知识,反重力背后的数学实际上非常简单。

    在图1中,标有“ F”的箭头显示了来自Crazy的作用在AntiGravityBot上的力的方向。 可以将力视为x和y方向的分量,如其他两个箭头所示。 分解力使我们能够简单地将x和y方向上所有重力点的所有力加在一起,从而产生x和y方向上的总力。

    图1.解决力

    为了防止我们的机器人受到遥远的机器人的影响,我们必须使用函数force = strength/Math.pow(distance,2)从重力点计算对机器人的force = strength/Math.pow(distance,2)其中力量是重力点的力量, 距离是指重力点与机器人之间的距离。 2的幂值不固定; 您可以使用3的值来避免只在非常接近该点时才使用该点。

    代码

    以下清单为您展示了基本的反重力系统的代码。 清单1显示了主要的反重力功能。 它在向量中的所有重力点之间循环,分解力,然后沿正确方向移动机器人。 我建议将敌方机器人指定为排斥点。 为此,您必须对战场保持最新状态,这意味着您的雷达必须经常旋转。

    清单1.反重力主力:antiGravMove()
    void antiGravMove() { double xforce = 0; double yforce = 0; double force; double ang; GravPoint p; for(int i = 0;i<gravpoints.size();i++) { p = (GravPoint)gravpoints.elementAt(i); //Calculate the total force from this point on us force = p.power/Math.pow(getRange(getX(),getY(),p.x,p.y),2); //Find the bearing from the point to us ang = normaliseBearing(Math.PI/2 - Math.atan2(getY() - p.y, getX() - p.x)); //Add the components of this force to the total force in their //respective directions xforce += Math.sin(ang) * force; yforce += Math.cos(ang) * force; } /**The following four lines add wall avoidance. They will only affect us if the bot is close to the walls due to the force from the walls decreasing at a power 3.**/ xforce += 5000/Math.pow(getRange(getX(), getY(), getBattleFieldWidth(), getY()), 3); xforce -= 5000/Math.pow(getRange(getX(), getY(), 0, getY()), 3); yforce += 5000/Math.pow(getRange(getX(), getY(), getX(), getBattleFieldHeight()), 3); yforce -= 5000/Math.pow(getRange(getX(), getY(), getX(), 0), 3); //Move in the direction of our resolved force. goTo(getX()-xforce,getY()-yforce); }

    清单2中所示的辅助方法使我们能够以最有效的方式移至某个点,并获得机器人与敌人之间的距离。

    清单2. Helper方法
    /**Move in the direction of an x and y coordinate**/ void goTo(double x, double y) { double dist = 20; double angle = Math.toDegrees(absbearing(getX(),getY(),x,y)); double r = turnTo(angle); setAhead(dist * r); } /**Turns the shortest angle possible to come to a heading, then returns the direction the bot needs to move in.**/ int turnTo(double angle) { double ang; int dir; ang = normalisebearing(getHeading() - angle); if (ang > 90) { ang -= 180; dir = -1; } else if (ang < -90) { ang += 180; dir = -1; } else { dir = 1; } setTurnLeft(ang); return dir; } /**/Returns the distance between two points**/ double getRange(double x1,double y1, double x2,double y2) { double x = x2-x1; double y = y2-y1; double range = Math.sqrt(x*x + y*y); return range; }

    最后,在清单3中,我们看到了GravPoint类,该类保存了重力点所需的所有数据。 请注意, power必须为负才能排斥。

    清单3. GravPoint类
    class GravPoint { public double x,y,power; public GravPoint(double pX,double pY,double pPower) { x = pX; y = pY; power = pPower; } }

    可以从下载中下载此技巧的完整资源。

    改善行为

    清单1至清单3中的代码产生了合理的行为,但战斗性能几乎令人叹为观止。 尽管该机器人通常远离其他机器人,但它倾向于卡在墙壁附近。 这样做的原因是,一旦机器人到达底壁,下面便没有机器人了。 因此,除了壁自身产生的排斥力之外,没有力将其推离壁。 由于壁排斥力的范围有限,因此会产生不良行为。

    为了解决这个问题,我使用了一个系统,将所有力量集中在赛场周围的一系列点上。 然后,我将推斥力值分配给在其上具有大于平均总力的点(这意味着它们附近有机器人),并将吸引力值分配给在其上具有小于平均总力的那些点。 然后,我解决这些新点对我的机器人的作用。 分配吸引力点时,必须格外小心。 如果您的机器人接近一个吸引力点,它将悬停在它上面,永不离开。 因此,我建议随机分配这些中间点的位置并定期更改其位置。

    我将留给您制定增强功能的代码。 请确保,上述代码仅作了少许改动,使用了与上述代码完全相同的基本原理。 作为进一步的提示,我建议使用force = strength/Math.pow(distance,1.5)来计算机器人中间点的力。

    其他增强功能

    反重力是一种非常灵活的技术,因此,讨论使用它产生的全部行为是不切实际的。 但是,这里有一些更有趣的内容:

    目标选择 :通过为您擅长击中或健康状况不佳的目标分配较低的排斥值,您可以靠近它们并捕食弱者。

    随机化 :您可能需要定期从x和y力中增加或减去随机量,以产生更多的随机运动,甚至偶尔停止,以欺骗敌人的目标瞄准系统。 我鼓励您实施这种行为。

    近战子弹躲避 :如果您知道何时有敌人向您开火,您可以将发射的子弹建模为反重力点。 如果您假设它是使用线性目标射击的,则可以每转一圈更新该重力点的位置并躲避子弹。 但是,此增强功能尚未被任何机器人完善。

    跟随领导者 :此增强功能为您的机器人创造了一个吸引人的关注点。 因此,您可以通过移动点来生成所需的任何模式(在robocode物理定律内),同时保留标准的反重力墙排斥力。


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

    相关资源:[主板驱动]Intel英特尔815EM芯片组(with AIM)公板视频部分最新BIOS PV6.3
    Processed: 0.011, SQL: 9