Melee Radar

From Robowiki
Jump to navigation Jump to search

Melee Radars are radars used in melee battles. They usually take much more space in a bot than one on one radars, because there are many more decisions that have to be made about where to scan (in one on one, all you have to do is try to scan your enemy as much as possible). Enemies usually are not all in one 45 degree area, which makes bots have to compromise on what information they receive each turn. There are two major groups of radar strategies: getting frequent data of one bot (e.g., the firing target) and consistently updating data of all bots.

Spinning radar

The most used radar both in melee and one on one is the generic spinning radar. It is by far the easiest to implement.

public void run() {
    // ...

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

Corner Arc

A variation on the spinning radar, if the robot is in a corner it scans back and forth across the 90 degree arc away from the corner, as not to waste time scanning where there cannot be any robots. Typically, this is used only in smaller melee robots, which do not have room for a more complicated radar system. Melee bots with room tend to use one of the implementations below.

Oldest Scanned

This type of melee radar spins towards the robot it hasn't seen in the longest amount of time. Here is an example of this type of radar.

import java.util.*;
import robocode.*;
import robocode.util.*;

// ... Within robot class

static LinkedHashMap<String, Double> enemyHashMap;
static double scanDir;
static Object sought;

public void run() {
    scanDir = 1;
    enemyHashMap = new LinkedHashMap<String, Double>(5, 2, true);

    // ...

    while(true) {
        setTurnRadarRightRadians(scanDir * Double.POSITIVE_INFINITY);
        scan();
    }
}

public void onRobotDeath(RobotDeathEvent e) {
    enemyHashMap.remove(e.getName());
    sought = null;
}

public void onScannedRobot(ScannedRobotEvent e) {
    String name = e.getName();
    LinkedHashMap<String, Double> ehm = enemyHashMap;

    ehm.put(name, getHeadingRadians() + e.getBearingRadians());

    if ((name == sought || sought == null) && ehm.size() == getOthers()) {
	scanDir = Utils.normalRelativeAngle(ehm.values().iterator().next()
            - getRadarHeadingRadians());
        sought = ehm.keySet().iterator().next();
    }

    // ...
}

With above code, the radar will spin past every bot, and then reverse it's direction until its passed all bots, then repeat. If the spin takes more than 4 ticks, the radar will continue spinning like the spinning radar above. This kind of radar is used in many top bots include Shadow and Phoenix. This kind of radar should be used unless you need a melee radar lock or your targeting system requires you to have enemy scans every 8 ticks.

Gun Heat Lock

A technique developed by Paul Evans/Kawagi for SandboxDT/FloodHT. This radar locks onto a target when this robot has low gunheat. Normally this is best for melee robots which use GuessFactor Targeting.

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

public void onScannedRobot(ScannedRobotEvent e) {
    // ... your own target selection
    double absoluteBearing = getHeadingRadians() + e.getBearingRadians();
    if (isCurrentTarget && getGunHeat() < 0.5) // Lock for 5 ticks
        setTurnRadarRightRadians(3.5 * Utils.normalRelativeAngle(absoluteBearing - getRadarHeadingRadians()));
    else
        setTurnRadarRightRadians(Double.POSITIVE_INFINITY); 
}

The code above uses a Narrow Lock but the simpler Infinity Lock works just as well. For a narrow lock, it is recommended you multiply by a large factor to continue scanning other robots while locked.

Small melee sweep radar

Basically a turn multiplier radar with the ability to turn clockwise and counterclockwise.

public void run() {
    setTurnRadarRightRadians(Double.POSTIVE_INFINITY)
}

public onScannedRobot(ScannedRobotEvent e) {
     // only works with some sort of scan break rule (like usual in melee)
    double turn;
    if (!Double.isNaN(turn = (Utils.normalRelativeAngle(rM - getRadarHeadingRadians()) * Double.POSTIVE_INFINITY))) {
        setTurnRadarRightRadians(turn);
    }
}

For a melee radar it is beneficial not to turn the radar always in one direction. This melee sweep radar has a higher average scan rate than the traditional multiplier radar and is more stable than the infinity lock radar.