你能解释一下robocode的代码是什么意思吗?

时间:2014-05-20 02:08:46

标签: java robocode

我不明白这种方法到底在做什么。有人可以向我解释这个问题吗?

public void onScannedRobot(ScannedRobotEvent e)
  {
    setTurnRadarLeftRadians(getRadarTurnRemaining());

    setTurnRight(e.getBearing() + 90.0D - dir / 33.0D);
    if (((Guppy.var = var - e.getEnergy()) <= 3) && (var > 0.0D))
    {
      setMaxVelocity(Math.random() * 9.0D + 3);
      setAhead(Guppy.dir = dir * type);
    }
    setTurnGunRightRadians(Math.sin((Guppy.var = e.getBearingRadians() + getHeadingRadians()) - getGunHeadingRadians() + Math.asin((vel * 0.4D + e.getVelocity() * 0.6D) / 14.0D * Math.sin(e.getHeadingRadians() - var))));
    if (getGunHeat() == 0.0D)
    {
      setFire(2.9D);
      vel = e.getVelocity();
    }
    var = e.getEnergy();
  }

2 个答案:

答案 0 :(得分:2)

熟悉三角函数而不是Robocode的人注意: Robocode的角度值是非负的并且顺时针增加,而不是零中心,并且像三角函数惯例那样逆时针增加。

圣牛,这是一个毛球。痛苦的风格,分配变量然后在同一表达式中使用它,并随机重用static变量用于不同的目的。 (编辑:我已经离开了robocode太长时间;看似模糊不清的混乱可能是code size手动优化的结果。)让我们试着去掉那一条凌乱的线,从这里开始:

setTurnGunRightRadians(Math.sin((Guppy.var = e.getBearingRadians() + getHeadingRadians()) - getGunHeadingRadians() + Math.asin((vel * 0.4D + e.getVelocity() * 0.6D) / 14.0D * Math.sin(e.getHeadingRadians() - var))));

看起来var用于保存子表达式e.getBearingRadians() + getHeadingRadians()的结果。由于e.getBearingRadians()会将目标相对返回到您的标题,var绝对 目标的承载即可。重构:

double targetBearing = e.getBearingRadians() + getHeadingRadians();
setTurnGunRightRadians(Math.sin(targetBearing - getGunHeadingRadians() + Math.asin((vel * 0.4D + e.getVelocity() * 0.6D) / 14.0D * Math.sin(e.getHeadingRadians() - targetBearing))));
唉,还是一团糟。我们还有变量vel未提及,但基于其余代码,它似乎是上次扫描时目标的速度(并且在皮疹假设下只会进行一对一的比赛);它与当前速度合并为加权平均值,以提供粗略的预测速度,因此可能存在一些目标主导逻辑。

double targetBearing = e.getBearingRadians() + getHeadingRadians();
double predictedVelocity = vel * 0.4D + e.getVelocity() * 0.6D;
setTurnGunRightRadians(Math.sin(targetBearing - getGunHeadingRadians() + Math.asin(predictedVelocity / 14.0D * Math.sin(e.getHeadingRadians() - targetBearing))));

由于robocode似乎忽略了航向和航向之间的差异,因此最里面的正弦Math.sin(e.getHeadingRadians() - targetBearing)给出了一个有符号系数,表明目标速度的哪个分量垂直于其承受因此需要调整角度。

double targetBearing = e.getBearingRadians() + getHeadingRadians();
double predictedVelocity = vel * 0.4D + e.getVelocity() * 0.6D;
double perpendicularMotionCoefficient = Math.sin(e.getHeadingRadians() - targetBearing);
setTurnGunRightRadians(Math.sin(targetBearing - getGunHeadingRadians() + Math.asin(predictedVelocity / 14.0D * perpendicularMotionCoefficient)));

弧正弦表达式似乎旨在将目标运动的垂直分量转换回角度调整。这个数学运算是完全错误的,因为反正弦不能这样工作:它将区间[-1,1]中的系数转回到区间中的角度[-pi / 2,pi / 2]并且将预测速度除以14可能只是试图将参数与反正弦限制在其范围内。再说一遍,目标的距离和射弹速度都没有进入计算,所以我能说的最好的调整就是模糊地朝着正确的方向前进。

double targetBearing = e.getBearingRadians() + getHeadingRadians();
double predictedVelocity = vel * 0.4D + e.getVelocity() * 0.6D;
double perpendicularMotionCoefficient = Math.sin(e.getHeadingRadians() - targetBearing);
double firingAngleAdjustment = Math.asin(predictedVelocity / 14.0D * perpendicularMotionCoefficient);
setTurnGunRightRadians(Math.sin(targetBearing - getGunHeadingRadians() + firingAngleAdjustment));

对我来说,最后的正弦对我毫无意义。 参数已经是角度,以弧度为单位,枪需要移动:目标的绝对方位减去当前的枪标(这是枪的距离)将需要转向精确指向目标),加上目标运动的射击角度调整。我完全删除那里的正弦函数。

double targetBearing = e.getBearingRadians() + getHeadingRadians();
double predictedVelocity = vel * 0.4D + e.getVelocity() * 0.6D;
double perpendicularMotionCoefficient = Math.sin(e.getHeadingRadians() - targetBearing);
double firingAngleAdjustment = Math.asin(predictedVelocity / 14.0D * perpendicularMotionCoefficient);
setTurnGunRightRadians(targetBearing - getGunHeadingRadians() + firingAngleAdjustment);

当然,这还取决于将枪设置为转动超过半圈(pi弧度)是否会被自动理解为将其转向另一个方向的半圈而不是......您可能最终会这样做否则就会发生许多毫无意义的枪械。

答案 1 :(得分:0)

    public void onScannedRobot(ScannedRobotEvent e) // for every robots that your robot see {
setTurnRadarLeftRadians(getRadarTurnRemaining()); // Sets the robot's radar to turn left by radians 
setTurnRight(e.getBearing() + 90.0D - dir / 33.0D); //   Sets the robot's body to turn right by degrees, basically you are depending it in your enemy
if (((Guppy.var = var - e.getEnergy()) <= 3) && (var > 0.0D))
{
  setMaxVelocity(Math.random() * 9.0D + 3); //Sets the maximum velocity of the robot measured in pixels/turn if the robot should move slower than Rules.MAX_VELOCITY (8 pixels/turn).
  setAhead(Guppy.dir = dir * type);
}
setTurnGunRightRadians(Math.sin((Guppy.var = e.getBearingRadians() + getHeadingRadians()) - getGunHeadingRadians() + Math.asin((vel * 0.4D + e.getVelocity() * 0.6D) / 14.0D * Math.sin(e.getHeadingRadians() - var))));
if (getGunHeat() == 0.0D)
{
  setFire(2.9D); // how big is the damage of the bullet. The bigger the damage= bigger energy consumed
  vel = e.getVelocity(); //get the enemy velocity
}
var = e.getEnergy(); // get the enemy energy

}

如果你想要,你可以玩我的这些迷你项目:

                    package sample;
                import robocode.*;
                import java.awt.Color;
                import java.awt.geom.*;
                import java.lang.*;         // for Double and Integer objects
                import java.util.*; // for collection of waves
                import robocode.util.Utils;

                import robocode.RobotDeathEvent;
                import robocode.Rules;
                import robocode.ScannedRobotEvent;
                import robocode.util.Utils;

                /*
            A Robocode that implements the smart targeting(always attack on the nearest opponent) and circles around them
                */

                public class Tutorial extends AdvancedRobot
                {   boolean movingForward;
                    boolean peek; // Don't turn if there's a robot there
                    double moveAmount; // How much to move
                    byte moveDirection= 1;
                    int tooCloseToWall = 0;
                    int wallMargin = 60;

                    static final double GUN_FACTOR = 30;
                    static final double AIM_FACTOR = 25;
                    static final int AIM_START = 10;
                    static final int FIRE_FACTOR = 100;
                    private long    currTime;               
                    static final long RADARTIMEOUT  = 20;
                    static double xForce;
                    static double yForce;
                    static double lastDistance;

                    private boolean radarScan;              
                    private long    lastscan;               

                    public void run(){

                        setAdjustRadarForGunTurn(true);
                        setAdjustGunForRobotTurn(true);

                        // Sets these colors (robot parts): body, gun, radar, bullet, scan_arc
                        setBodyColor(new Color(255, 255, 255));
                        setGunColor(new Color(255, 255, 255));
                        setRadarColor(new Color(255, 255, 255));
                        setBulletColor(new Color(0, 0, 0));
                        setScanColor(new Color(255, 255, 255));

                        while(true) {
                            currTime = getTime();
                            turnRadarRightRadians(Double.POSITIVE_INFINITY);
                            turnRadarLeftRadians(Double.POSITIVE_INFINITY);
                            radarScan = true;
                        }
                    }

                    public void onScannedRobot(ScannedRobotEvent e) {

                        double absoluteBearing = e.getBearingRadians()+ getHeadingRadians();
                        double  distance = e.getDistance();
                        double  bulletPower ;
                        double headingRadians = getHeadingRadians();
                        boolean fired = false;

                        if(getOthers() >= 2){

                            xForce = xForce *.80- Math.sin(absoluteBearing) / distance;
                            yForce = yForce *.80 - Math.cos(absoluteBearing) / distance;

                        setTurnRightRadians(Utils.normalRelativeAngle(
                            Math.atan2(xForce + 1/getX() - 1/(getBattleFieldWidth() - getX()), 
                                       yForce + 1/getY() - 1/(getBattleFieldHeight() - getY()))
                                        - getHeadingRadians()) );
                        setAhead(150- Math.abs(getTurnRemaining()));//speed
                        bulletPower = ( distance > 850 ? 0.1 : (distance > 700 ? 0.49 : (distance > 250 ? 1.9 : 3.0)));
                                bulletPower = Math.min( getEnergy()/5, Math.min( (e.getEnergy()/4) + 0.2, bulletPower));

                        if ((getGunHeat() <= 3.0) && (getGunTurnRemaining() == 0.0) && (bulletPower > 0.0) && (getEnergy() > 9.1)) {
                        // Only fire the gun when it is locked and loaded, do a radarsweep afterwards.
                        bulletPower=3;
                        setFire( bulletPower);
                        fired = true;
                        }
                        if ((fired == true) || (currTime >= (lastscan + RADARTIMEOUT))) {
                            setTurnRadarRightRadians( Double.NEGATIVE_INFINITY * Utils.normalRelativeAngle( absoluteBearing- getRadarHeadingRadians()));
                            lastscan = currTime;
                            radarScan = true;
                        }

                        // when not firing, lock on target.
                        //setTurnRadarRightRadians( 2.2 * Utils.normalRelativeAngle( absoluteBearing - getRadarHeadingRadians()));
                        //radarScan = false;

                        lastDistance = Double.POSITIVE_INFINITY;
                        setTurnRadarLeft(getRadarTurnRemaining());
                        setTurnRadarRight(getRadarTurnRemaining());

                        if(lastDistance+20 > distance){
                            lastDistance = distance;
                            if(getGunHeat() < .1){
                                setTurnRadarLeft(getRadarTurnRemaining());
                                setTurnRadarRight(getRadarTurnRemaining());
                                clearAllEvents();
                            }
                            setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians() + Math.max(1 - distance / (40), 0) * (e.getVelocity() / (AIM_START + Math.pow(AIM_FACTOR, distance))) * Math.sin(e.getHeadingRadians() - absoluteBearing) ));       
                            }
                    }

                        if(getOthers() == 1){

                            setBodyColor(new Color(255, 0, 0));
                            setGunColor(new Color(255,  0, 0));
                            setRadarColor(new Color(255, 0, 0));
                            setBulletColor(new Color(255, 0, 0));
                            setScanColor(new Color(255, 0, 0));

                            double bulletPower1 = 3;
                            if(distance >= 700){
                                lastDistance = Double.POSITIVE_INFINITY;
                            }

                            else if (distance < 700 && distance > 500){
                                bulletPower = 3 - (( 24.5- getEnergy()) / 6);
                                if (getEnergy() >= 3.1 ) {
                                    setFire(bulletPower);
                                    lastDistance = Double.POSITIVE_INFINITY;
                                }
                                else{
                                    lastDistance = Double.POSITIVE_INFINITY;
                                }
                            }

                        else if (distance <=500 && distance >=350){
                            bulletPower = 3 - (( 17.5- getEnergy()) / 6);
                            if (getEnergy() >= 3.1 ) {
                                setFire(bulletPower);
                                lastDistance = Double.POSITIVE_INFINITY;
                            }
                            else{
                                lastDistance = Double.POSITIVE_INFINITY;
                            }
                        }

                        else if (distance < 350 ){
                            bulletPower = 3 - (( 5- getEnergy()) / 6);
                            if (getEnergy() >= 3.1 ) {
                                setFire(bulletPower);
                                lastDistance = Double.POSITIVE_INFINITY;
                            }
                            else{
                                lastDistance = Double.POSITIVE_INFINITY;
                            }
                        }

                    if(lastDistance+25 > distance){
                        lastDistance = distance;
                        if(getGunHeat() < .1){
                                setTurnRadarLeft(getRadarTurnRemaining());
                                setTurnRadarRight(getRadarTurnRemaining());
                                clearAllEvents();
                        clearAllEvents();
                    }
                setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians() + Math.max(1 - distance / (400), 0) * (e.getVelocity() / (AIM_START + Math.pow(AIM_FACTOR, distance))) * Math.sin(e.getHeadingRadians() - absoluteBearing) ));      
                }
                    wall();
                    // always square off against our enemy, turning slightly toward him
                    setTurnRight(e.getBearing() + 90 - (10 * moveDirection));
                    // if we're close to the wall, eventually, we'll move away
                    if (tooCloseToWall > 0) tooCloseToWall--;
                    // normal movement: switch directions if we've stopped
                    if (getVelocity() == 0) {
                        setMaxVelocity(8);
                        moveDirection *= -1;
                        setAhead(500 * moveDirection);
                    }
            }
    }   

                    public void onHitByBullet(HitByBulletEvent e) {
                        setTurnRadarLeft(getRadarTurnRemaining());
                        setTurnRadarRight(getRadarTurnRemaining());
                        clearAllEvents();
                    }

                    public void onBulletMissed(BulletMissedEvent e) {
                        setTurnRadarLeft(getRadarTurnRemaining());
                        setTurnRadarRight(getRadarTurnRemaining());
                        clearAllEvents();
                    }

                    public void onHitRobot(HitRobotEvent e) {
                        setTurnRadarLeft(getRadarTurnRemaining());
                        setTurnRadarRight(getRadarTurnRemaining());
                        clearAllEvents();
                    }

                    public void wall(){
                    //close to left, right, bottom, top wall
                    if(getX() <= wallMargin || getX() >= getBattleFieldWidth() - wallMargin || getY() <= wallMargin || getY() >= getBattleFieldHeight() - wallMargin){
                    if(tooCloseToWall <= 0){
                    // coming near the wall
                        tooCloseToWall += wallMargin;
                        setMaxVelocity(0); // stop!!!
                    }
            }
    }   

}