1

I am trying to go to the center of the map directly. So this means no turning to the center of the map height, then the center of the map width, I want to start and face the center and go there. Once I am there, I want to stop. I feel like what I have should do it, but it doesn't work properly.

1) Am I on the right track?

2) Is there an easier way to go to the center directly? Like a way to just spell out coordinates?

So far I have:

public void run() {
    // Initialization of the robot should be put here
    setColors(Color.black,Color.blue,Color.orange, Color.orange, Color.cyan); // body,gun,radar

    double xMiddle = getBattleFieldWidth() / 2;
    double yMiddle = getBattleFieldHeight() / 2;
    double directionToTurn = 0;

    // Robot main loop
    while(true) {

        if( (int)getX() != xMiddle && (int)getY() != yMiddle ){
            if ( (int)getX() > xMiddle && (int)getY() > yMiddle ) { //Quadrant 1
                directionToTurn = (int)getHeading() - 225;
                System.out.println("Quadrant: ONE ");
            } else if ( (int)getX() < xMiddle && (int)getY() > yMiddle ) { //Quadrant 2
                directionToTurn = (int)getHeading() - 135;
                System.out.println("Quadrant: TWO ");

            } else if ( (int)getX() < xMiddle && (int)getY() < yMiddle ) { //Quadrant 3
                directionToTurn = (int)getHeading() - 45;
                System.out.println("Quadrant: THREE ");

            } else if ( (int)getX() > xMiddle && (int)getY() < yMiddle ) { //Quadrant 4
                directionToTurn = (int)getHeading() - 315;
                System.out.println("Quadrant: FOUR ");

            } else if ( (int)getX() > xMiddle && (int)getY() == yMiddle ) { // Right Center
                directionToTurn = (int)getHeading() - 270;
                System.out.println("Quadrant: Right Center ");
            } else if ( (int)getX() < xMiddle && (int)getY() == yMiddle ) { // Left Center
                directionToTurn = (int)getHeading() - 90;
                System.out.println("Quadrant: Left Center ");
            } else if ( (int)getX() == xMiddle && (int)getY() > yMiddle ) { // Top Center
                directionToTurn = (int)getHeading() - 180;
                System.out.println("Quadrant: Top Center ");
            } else if ( (int)getX() == xMiddle && (int)getY() < yMiddle ) { // Bottom Center
                directionToTurn = (int)getHeading() - 0;
                System.out.println("Quadrant: Bottom Center ");
            }
            turnLeft( directionToTurn );
            System.out.println("Position: ("+(int)(getX())+", "+(int)getY()+"), Facing: "+(int)getHeading() );
            ahead(1);
        }
    }
}
Freiermuth
  • 133
  • 4
  • 15
  • Are you limited to the 8 cardinal directions? Could you use static Math methods to calculate an angle and take a heading of, for example, 203? That would let you have a method calcHeading() and get rid of all those conditionals. – nexus_2006 Sep 15 '13 at 03:39
  • 1
    Are you familiar with `atan2()`? – Adam Burry Sep 15 '13 at 03:40
  • @nexus_2006 No I am not limited to 8 directions. I guess that is what I am trying to do here is calculate the direction I should go in. – Freiermuth Sep 15 '13 at 03:42

2 Answers2

2

What you want to calculate is a bearing. A bearing is the difference between your heading (the direction you are facing) and the direction to a target. If you turn by the amount of the bearing then you will be facing the target.

It has been a long time since I played with Robocode so I do not recall the exact API. The following is a sketch (therefore, untested). You will have to fix the function names and types before it will compile.

// heading (or course) [0, 2pi): 0 is up, rotation is clock-wise
// bearing (-pi, pi]: positive is clock-wise

// convert angle to (-pi, pi]
double norm(double a) {
  // do something smarter with modulus (%) here
  while (a <= -Math.PI) a += 2 * Math.PI;
  while (Math.PI < a) a -= 2 * Math.PI;
  return a;
}

// get bearing in radians to a target(x,y) from the current position/heading
double getBearing(int x, int y) {
  // can rotate the coordinate system to avoid the addition of pi/2 if you like 
  double b = Math.PI/2 - Math.atan2(y - robot.y(), x - robot.x());
  return norm(b - robot.getHeadingRadians());
}

// then bearing to centre is
double bearingToCentre = getBearing(xMiddle, yMiddle);
Adam Burry
  • 1,904
  • 13
  • 20
  • Thanks, it seems that the bearing is what I am looking for. Is robot.headingRad() supposed to be getting the headings in radians? – Freiermuth Sep 16 '13 at 13:40
0

In case anyone needs this:

private void moveTowardsCenter() {
    double centerAngle = Math.atan2(getBattleFieldWidth()/2-getX(), getBattleFieldHeight()/2-getY());
    setTurnRightRadians(Utils.normalRelativeAngle(centerAngle - getHeadingRadians()));
    setAhead(100);
}

Its what @Adam-burry explained, but tested and compiles :D

Salvatorelab
  • 11,614
  • 6
  • 53
  • 80