Difference between revisions of "One on One Radar"

From Robowiki
Jump to navigation Jump to search
(Needlessly many youtube links, just one per video please. Also please try to give them useful descriptions if you have more then one per article.)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
'''One on One Radars''' are [[Radar|radars]] that are used for [[One on One]] battles. They usually produce a perfect lock by scanning an enemy every turn.
 
'''One on One Radars''' are [[Radar|radars]] that are used for [[One on One]] battles. They usually produce a perfect lock by scanning an enemy every turn.
  
== Simple Radars == {{Youtube|75sU-AJxZm0|Simple Radars}}
+
== Simple Radar Locks == {{Youtube|75sU-AJxZm0|Simple Radar Locks}}
 
These radars are the simplest to write and usually produce the smallest bytecode, which is useful with codesize restrictions.
 
These radars are the simplest to write and usually produce the smallest bytecode, which is useful with codesize restrictions.
  
Line 15: Line 15:
 
         turnRadarRightRadians(Double.POSITIVE_INFINITY);
 
         turnRadarRightRadians(Double.POSITIVE_INFINITY);
 
     } while (true);
 
     } while (true);
 +
}
 +
</syntaxhighlight>
 +
 +
A slightly smaller implementation can be achieved with using onStatus(..) instead of run(). This saves the bytes for the loop and can also be used for turn multiplier and width lock radars.
 +
 +
<syntaxhighlight>
 +
public void onStatus( StatusEvent e) {
 +
    // you can also put all setAdjustXX(..) methods here
 +
    setTurnRadarRightRadians(Double.POSITIVE_INFINITY);
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 34: Line 43:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Perfect radar locks == {{Youtube|4TUwwjP4KNk|Perfect Radars}}
+
== Perfect Radar Locks == {{Youtube|4TUwwjP4KNk|Perfect Radar Locks}}
 
There are several "perfect" radar locks that will not slip once they have a lock.
 
There are several "perfect" radar locks that will not slip once they have a lock.
  
Line 95: Line 104:
 
         if ( getRadarTurnRemaining() == 0.0 )
 
         if ( getRadarTurnRemaining() == 0.0 )
 
             setTurnRadarRightRadians( Double.POSITIVE_INFINITY );
 
             setTurnRadarRightRadians( Double.POSITIVE_INFINITY );
 +
       
 
         execute();
 
         execute();
 
     } while ( true );
 
     } while ( true );
Line 117: Line 127:
 
     // Basically if we were going to turn it left, turn it even more left, if right, turn more right.
 
     // Basically if we were going to turn it left, turn it even more left, if right, turn more right.
 
     // This allows us to overshoot our enemy so that we get a good sweep that will not slip.
 
     // This allows us to overshoot our enemy so that we get a good sweep that will not slip.
     radarTurn += (radarTurn < 0 ? -extraTurn : extraTurn);
+
     if (radarTurn < 0)
+
        radarTurn -= extraTurn;
 +
    else
 +
        radarTurn += extraTurn;
 +
   
 
     //Turn the radar
 
     //Turn the radar
 
     setTurnRadarRightRadians(radarTurn);
 
     setTurnRadarRightRadians(radarTurn);

Latest revision as of 01:58, 9 May 2017

One on One Radars are radars that are used for One on One battles. They usually produce a perfect lock by scanning an enemy every turn.

Simple Radar Locks

Youtube
Youtube has a video of Simple Radar Locks in action: click here to watch

These radars are the simplest to write and usually produce the smallest bytecode, which is useful with codesize restrictions.

Spinning radar

A simple spin of the radar, this is very ineffective in one on one, but still used in NanoBots.

Here is an example of this type of radar:

public void run() {
    // ...

    do {
        turnRadarRightRadians(Double.POSITIVE_INFINITY);
    } while (true);
}

A slightly smaller implementation can be achieved with using onStatus(..) instead of run(). This saves the bytes for the loop and can also be used for turn multiplier and width lock radars.

public void onStatus( StatusEvent e) {
    // you can also put all setAdjustXX(..) methods here 
    setTurnRadarRightRadians(Double.POSITIVE_INFINITY);
}

The Infinity Lock

The infinity lock is the simplest radar lock and it is used frequently in NanoBots. It has the disadvantage of "slipping" and losing its lock frequently. But is a much better alternative to the Spinning radar in one on one combat.

Here is an example of this type of radar:

public void run() {
    // ...
    turnRadarRightRadians(Double.POSITIVE_INFINITY);
}

public void onScannedRobot(ScannedRobotEvent e) {
    // ...
    setTurnRadarLeftRadians(getRadarTurnRemainingRadians());
}

Perfect Radar Locks

Youtube
Youtube has a video of Perfect Radar Locks in action: click here to watch

There are several "perfect" radar locks that will not slip once they have a lock.

Turn Multiplier Lock

Point the radar at the enemy's last known location. This results in a thin beam which follows the enemy around the battlefield. Many recent one on one bots use this type of radar. This radar lock is similar to, and considered an enhancement on the wide radar lock described below.

If implemented correctly, it is not possible for the enemy escape this lock. A robot's width is 36px (that's 18px from the middle) and it can only move at up to 8px/turn, so if your beam is pointing at its centre, it won't be able to move entirely out of it in one turn. However, a robot will only automatically scan for enemies if its radar is turning, which might not happen if you are using a Narrow Lock and your enemy decides to stay still for 2 turns. For this reason, if you decide to use an unmultiplied lock, you must call scan() yourself to avoid losing lock. Furthermore, if you skip turns, your enemy might be able to move out from your radar beam before you recover.

To overcome these issues, a Narrow Lock is often multiplied by a factor (as described below) to keep the radar moving and ensure the enemy does not escape the scan arc.

Here is an example of this kind of radar:

import robocode.util.Utils;

public void run() {
    // ...

    turnRadarRightRadians(Double.POSITIVE_INFINITY);
    do {
        // Check for new targets.
        // Only necessary for Narrow Lock because sometimes our radar is already
        // pointed at the enemy and our onScannedRobot code doesn't end up telling
        // it to turn, so the system doesn't automatically call scan() for us
        // [see the javadocs for scan()].
        scan();
    } while (true);
}

public void onScannedRobot(ScannedRobotEvent e) {
    double radarTurn =
        // Absolute bearing to target
        getHeadingRadians() + e.getBearingRadians()
        // Subtract current radar heading to get turn required
        - getRadarHeadingRadians();

    setTurnRadarRightRadians(Utils.normalRelativeAngle(radarTurn));

    // ...
}

The following factors affect the behaviour in the following ways (eg. factor * Utils.normalRelativeAngle(radarTurn))

  • 1.0 - Thin radar lock. Must call scan() to avoid losing lock. God help you if you ever skip a turn.
  • 1.9 - Radar arc starts wide and slowly narrows as much as possible while staying on target.
  • 2.0 - Radar arc sweeps through a fixed angle. Exact angle chosen depends on positions of enemy and radar when enemy is first picked up. Angle will be increased if necessary to maintain a lock. Most used corrective factor.

Width Lock

The Width Radar Lock or Wide Radar Lock tries to scan a fixed distance to either side of the enemy. It was to the best of knowledge created before the Turn Multiplier or Narrow Radar Lock. Its constant motion means the radar will not slip as long as you don't miss any turns.

Here is an example of this type of radar:

import robocode.util.Utils;

public void run() {
    // ...

    do {
        // ...
        // Turn the radar if we have no more turn, starts it if it stops and at the start of round
        if ( getRadarTurnRemaining() == 0.0 )
            setTurnRadarRightRadians( Double.POSITIVE_INFINITY );
        
        execute();
    } while ( true );
    
    // ...
}

public void onScannedRobot(ScannedRobotEvent e) {
    // ...

    // Absolute angle towards target
    double angleToEnemy = getHeadingRadians() + e.getBearingRadians();

    // Subtract current radar heading to get the turn required to face the enemy, be sure it is normalized
    double radarTurn = Utils.normalRelativeAngle( angleToEnemy - getRadarHeadingRadians() );

    // Distance we want to scan from middle of enemy to either side
    // The 36.0 is how many units from the center of the enemy robot it scans.
    double extraTurn = Math.min( Math.atan( 36.0 / e.getDistance() ), Rules.RADAR_TURN_RATE_RADIANS );

    // Adjust the radar turn so it goes that much further in the direction it is going to turn
    // Basically if we were going to turn it left, turn it even more left, if right, turn more right.
    // This allows us to overshoot our enemy so that we get a good sweep that will not slip.
    if (radarTurn < 0)
        radarTurn -= extraTurn;
    else
        radarTurn += extraTurn;
    
    //Turn the radar
    setTurnRadarRightRadians(radarTurn);

    // ...
}

You can replace 36.0 with any distance you want covered.