简体   繁体   English

Robocode BasicBot 进入地图中间......不是

[英]Robocode BasicBot Going To The Middle Of The Map... Not

This is one of the classic Robocode practice questions: Going to the middle of the map.这是经典的 Robocode 练习题之一:走到地图中间。 I didn't want to move twice (once for x-axis and once for y-axis), but instead get the bearing towards the middle and move in a single motion after setting my robot's bearing.我不想移动两次(一次用于 x 轴,一次用于 y 轴),而是将轴承移向中间并在设置机器人的轴承后以单一动作移动。

To my dismay, it seems to be not working.令我沮丧的是,它似乎不起作用。 Instead, the behavior I observed from the robots is that they turn 180 degrees and move ahead for the value of 'r', which is the hypotenuse of the "triangle" towards the middle.相反,我从机器人身上观察到的行为是它们旋转 180 度并向前移动“r”的值,这是“三角形”向中间的斜边。 The distance seems to be getting smaller each loop, so I think that the formula for 'r' is right.每个循环的距离似乎越来越小,所以我认为 'r' 的公式是正确的。 My suspicion is towards the methods setWest() and setEast() I wrote.我怀疑是针对我写的setWest()setEast()方法。 Their purpose is to set the robot parallel to the horizontal facing either East or West.他们的目的是让机器人平行于水平面朝东或朝西。 Then I once again rotate the robot towards the middle by using theta (which is the second iffy part) and move it.然后我再次使用 theta(这是第二个 iffy 部分)将机器人向中间旋转并移动它。

The methods implemented in Robocode are pretty self-explanatory, not mine though. Robocode 中实现的方法是不言自明的,但不是我的。 Here is the code I've written:这是我写的代码:

public class MyFirstRobot extends Robot {   
    public void setWest(){  
        // If it's looking NW           
        if(getHeading() > 270 && getHeading() < 0)
            turnLeft(getHeading() - 270);
        // If it's looking SE or SW
        else if(getHeading() >= 90 && getHeading() <= 270)
            turnRight(270 - getHeading());
        // If it's looking NE
        else if(getHeading() >= 0 && getHeading() < 90)
            turnLeft(90 + getHeading());
        // If my coding is undercooked spaghetti
        else {
            System.out.println("Error");
        }   
    }
    
    public void setEast(){  
        // If it's looking NW       
        if(getHeading() > 270 && getHeading() < 0)
            turnRight(450 - getHeading());
        // If it's looking SE or SW
        else if(getHeading() >= 90 && getHeading() <= 270)
            turnLeft(getHeading() - 90);
        // If it's looking NE
        else if(getHeading() >= 0 && getHeading() < 90)
            turnRight(90 - getHeading());
        // If my coding is undercooked spaghetti
        else {
            System.out.println("Error");        
        }
    }
    
    public void run() {
        double x = 0.0;
        double y = 0.0;
        double r = 0.0;     
        double theta = 0.0;
        
        while (true) {
            x = getBattleFieldWidth() / 2.0 - getX();
            y = getBattleFieldHeight() / 2.0 - getY();
            r = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
            // Find the angle with respect to the horizontal.
            theta = Math.atan((Math.toRadians(y) / Math.toRadians(x)));
        
            /* 
             * Align tank towards the middle
             * depending on the "quadrant" it's in.
             */

            // 1st Quadrant
            if(x < 0 && y < 0){
                setWest();
                turnLeft(theta);
            }
                                    
            // 2nd Quadrant
            else if(x >= 0 && y < 0){
                setEast();
                turnRight(theta);
            }
            
            // 3rd Quadrant
            else if(x >= 0 && y >= 0) {
                setEast();
                turnLeft(theta);
            }
            
            // 4th Quadrant
            else if(x < 0 && y >= 0) {
                setWest();
                turnRight(theta);
            }
            
            // Move to the middle after the final rotation.
            ahead(r);   
        }
    }

Please don't mind the infinite loop, it's just to observe the behavior.请不要介意无限循环,这只是为了观察行为。 run() is the main method of the robot; run()是机器人的主要方法; it is called by default.默认情况下会调用它。

I will answer my own question in case someone wonders what the answer is.如果有人想知道答案是什么,我将回答我自己的问题。 There were a few fixes:有一些修复:

  1. getHeading() returns a value between 0 <= getHeading() < 360 in degrees. getHeading()返回 0 <= getHeading() < 360 度之间的值。 I mistakenly set one of the if conditions to getHeading() < 0 , which isn't possible.我错误地将 if 条件之一设置为getHeading() < 0 ,这是不可能的。 I also decided to store the heading in a variable to avoid calling getHeading() multiple times.我还决定将标题存储在一个变量中,以避免多次调用getHeading() Here is the fix for that part:这是该部分的修复:

     public void setWest(){ double heading = getHeading(); // If it's looking NW if(heading > 270.0 && heading < 360.0) turnLeft(getHeading() - 270); // If it's looking SE or SW else if(heading >= 90.0 && heading <= 270.0) turnRight(270 - getHeading()); // If it's looking NE else if(heading >= 0.0 && heading < 90.0) turnLeft(90 + getHeading()); // If my coding is god awful else { System.out.println("West | Error"); }

The difference here being 0.0 for the first check being changed to 360.0 0.这里的差异是第一次检查的 0.0 更改为 360.0 0。

  1. Theta was stored in radians instead of degrees. Theta 以弧度而不是度数存储。 turnLeft() or turnRight() needs a parameter in degrees for it to work properly. turnLeft()turnRight()需要一个以度为单位的参数才能正常工作。 Putting in radians won't give you an error.输入弧度不会给你一个错误。 It also won't work as intended.它也不会按预期工作。 Theta also had to be stored as a positive number, since setWest() and setEast() already accounts for the direction. Theta 也必须存储为正数,因为setWest()setEast()已经考虑了方向。 It was simply fixed by using Math.abs() and Math.toDegrees() .它只是通过使用Math.abs()Math.toDegrees()Math.abs() As shown below:如下所示:

     // Find the abs value of the angle with respect to the horizontal. theta = Math.abs(Math.toDegrees(Math.atan((Math.toRadians(y) / Math.toRadians(x)))));

If you had some lingering questions about it, I hope this helped.如果您对此有一些挥之不去的问题,我希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM