[Home]ARAMtocles

Robo Home | Changes | Preferences | AllPages

Difference (from prior major revision) (minor diff, author diff)

Added: 11a12,17

History




* 0.3: rating 1598 (NanoDeath - 22)
* 0.2: rating 1599 (NanoDeath - 21)
* 0.1: rating 1608 (NanoDeath - 12)


Changed: 32c38,39
*
* v0.3 20060217 Removed reverse wall stuff.
* Rearranged distance segmentation and bulletpower. 707 bytes

Changed: 36,41c43,46
static Rectangle2D.Double fireField; // the shootable battlefield


static final double MAX_DISTANCE = 300;
static final double MAX_BULLET_POWER = 3.0;
static final double BULLET_POWER = 1.9;
static final double MAX_DISTANCE = 450;
static final double BULLET_SWITCH_DISTANCE = 180;
static final double MAX_BULLET_POWER = 3.0; // first two distance segments
static final double BULLET_POWER = 1.9; // third and fourth distance segment

Changed: 44c49
static final int DISTANCE_INDEXES = 3;
static final int DISTANCE_INDEXES = 5;

Changed: 47c52
static final int WALL_INDEXES = 3;
static final int WALL_INDEXES = 2;

Changed: 49c54
static final int AIM_FACTORS = 33;
static final int AIM_FACTORS = 25;

Added: 51a57
static Rectangle2D.Double fireField; // the shootable battlefield

Changed: 57c63
static int[][][][][][][] aimFactors = new int[DISTANCE_INDEXES][VELOCITY_INDEXES][LAST_VELOCITY_INDEXES][DECCEL_TIME_INDEXES][WALL_INDEXES][WALL_INDEXES][AIM_FACTORS];
static int[][][][][][] aimFactors = new int[DISTANCE_INDEXES][VELOCITY_INDEXES][LAST_VELOCITY_INDEXES][DECCEL_TIME_INDEXES][WALL_INDEXES][AIM_FACTORS];

Changed: 64c70
setColors( Color.red, Color.blue, Color.yellow);
setColors( Color.red, Color.blue, Color.yellow);

Changed: 66c72
fireField = new Rectangle2D.Double( WALL_MARGIN, WALL_MARGIN, getBattleFieldWidth?() - WALL_MARGIN * 2, getBattleFieldHeight?() - WALL_MARGIN * 2);
fireField = new Rectangle2D.Double( WALL_MARGIN, WALL_MARGIN, getBattleFieldWidth?() - WALL_MARGIN * 2, getBattleFieldHeight?() - WALL_MARGIN * 2);

Changed: 68,75c74,81
// Let gun and radar move independently
setAdjustGunForRobotTurn( true);
setAdjustRadarForGunTurn( true);

// mainloop
do {
turnRadarRight?( Double.NEGATIVE_INFINITY);
} while(true);
// Let gun and radar move independently
setAdjustGunForRobotTurn( true);
setAdjustRadarForGunTurn( true);

// mainloop
do {
turnRadarRight?( Double.NEGATIVE_INFINITY);
} while(true);

Changed: 83,84c89,90
double tmpbearing = getHeadingRadians() + e.getBearingRadians?();
double turnAngle;
double tmpbearing = getHeadingRadians() + e.getBearingRadians?();
double turnAngle;

Changed: 86,87c92,93
// Lock target with radar
setTurnRadarRightRadians( 2.2 * Utils.normalRelativeAngle( tmpbearing - getRadarHeadingRadians?()));
// Lock target with radar
setTurnRadarRightRadians( 2.2 * Utils.normalRelativeAngle( tmpbearing - getRadarHeadingRadians?()));

Changed: 89,120c95,127
// perform Aristocles targeting
Wave wave = new Wave();
double enemyAbsoluteBearing? = getHeadingRadians() + e.getBearingRadians?();
enemyLocation = project(wave.wGunLocation? = new Point2D.Double(getX(), getY()), enemyAbsoluteBearing?, enemyDistance = e.getDistance());

int lastVelocityIndex? = (int)Math.abs(enemyVelocity) / 2;
int velocityIndex = (int)Math.abs((enemyVelocity = e.getVelocity()) / 2);
if (velocityIndex < lastVelocityIndex?) {
timeSinceDeccel? = 0;
}

if (enemyVelocity != 0) {
bearingDirection = enemyVelocity * Math.sin(e.getHeadingRadians() - enemyAbsoluteBearing?) > 0 ?
0.7 / (double)MIDDLE_FACTOR : -0.7 / (double)MIDDLE_FACTOR;
}
wave.wBearingDirection? = bearingDirection;

int distanceIndex = (int)Math.min(DISTANCE_INDEXES - 1, enemyDistance / (MAX_DISTANCE / DISTANCE_INDEXES));
wave.wBulletPower? = enemyDistance > 120 ? BULLET_POWER : MAX_BULLET_POWER;

wave.wAimFactors? = aimFactors[distanceIndex][velocityIndex][lastVelocityIndex?][Math.min(DECCEL_TIME_INDEXES - 4, timeSinceDeccel?++ / 13)]
[wallIndex(wave, 1)][wallIndex(wave, -1)];

wave.wBearing = enemyAbsoluteBearing?;

int mostVisited = MIDDLE_FACTOR, i = AIM_FACTORS;
do {
if (wave.wAimFactors?[--i] > wave.wAimFactors?[mostVisited]) {
mostVisited = i;
}
} while (i > 0);
// end of Aristocles gun
// perform Aristocles targeting
Wave wave = new Wave();
double enemyAbsoluteBearing? = getHeadingRadians() + e.getBearingRadians?();
enemyLocation = project(wave.wGunLocation? = new Point2D.Double(getX(), getY()), enemyAbsoluteBearing?, enemyDistance = e.getDistance());

int lastVelocityIndex? = (int)Math.abs(enemyVelocity) / 2;
int velocityIndex = (int)Math.abs((enemyVelocity = e.getVelocity()) / 2);
if (velocityIndex < lastVelocityIndex?) {
timeSinceDeccel? = 0;
}

if (enemyVelocity != 0) {
bearingDirection = enemyVelocity * Math.sin(e.getHeadingRadians() - enemyAbsoluteBearing?) > 0 ?
0.7 / (double)MIDDLE_FACTOR : -0.7 / (double)MIDDLE_FACTOR;
}
wave.wBearingDirection? = bearingDirection;

int distanceIndex = (int)Math.min(DISTANCE_INDEXES - 1, enemyDistance / (MAX_DISTANCE / DISTANCE_INDEXES));
wave.wBulletPower? = enemyDistance > BULLET_SWITCH_DISTANCE ? BULLET_POWER : MAX_BULLET_POWER;
//wave.wBulletPower? = MAX_BULLET_POWER; // TargetingChallenge

wave.wAimFactors? = aimFactors[distanceIndex][velocityIndex][lastVelocityIndex?][Math.min(DECCEL_TIME_INDEXES - 1, timeSinceDeccel?++ / 13)]
[fireField.contains(project(wave.wGunLocation?, enemyAbsoluteBearing? + wave.wBearingDirection? * 13, enemyDistance)) ? 1 : 0];

wave.wBearing = enemyAbsoluteBearing?;

int mostVisited = MIDDLE_FACTOR, i = AIM_FACTORS;
do {
if (wave.wAimFactors?[--i] > wave.wAimFactors?[mostVisited]) {
mostVisited = i;
}
} while (i > 0);
// end of Aristocles gun

Changed: 122,123c129,130
// Turn gun (still Aristocles, but keep tmpbearing for movement)
tmpbearing = enemyAbsoluteBearing? + wave.wBearingDirection? * (mostVisited - MIDDLE_FACTOR);
// Turn gun (still Aristocles, but keep tmpbearing for movement)
tmpbearing = enemyAbsoluteBearing? + wave.wBearingDirection? * (mostVisited - MIDDLE_FACTOR);

Changed: 126,137c133,143
// Aristocles
setFire(wave.wBulletPower?);
if (getEnergy() >= 0) {
addCustomEvent(wave);
}
// GT: Move towards target
turnAngle = Utils.normalRelativeAngle( tmpbearing - getHeadingRadians());
setTurnRightRadians?( Math.atan( Math.tan( turnAngle)));
setAhead( Double.POSITIVE_INFINITY * Math.cos( turnAngle));

// Helps in melee to lock onto nearest target.
// clearAllEvents?();
if (enemyDistance <= (2 * BULLET_SWITCH_DISTANCE)) {
setFire(wave.wBulletPower?);
}
// Aristocles
if (getEnergy() >= BULLET_POWER) {
addCustomEvent(wave);
}
// GT: Move towards target
turnAngle = Utils.normalRelativeAngle( tmpbearing - getHeadingRadians());
setTurnRightRadians?( Math.atan( Math.tan( turnAngle)));
setAhead( Double.POSITIVE_INFINITY * Math.cos( turnAngle));

Changed: 146,151c152,157
//Victory? dance
setTurnGunRight( Double.POSITIVE_INFINITY);
setTurnRadarLeft( Double.POSITIVE_INFINITY);
setTurnRight?(10);
ahead(10);
waitFor(new RadarTurnCompleteCondition?(this));
//Victory? dance
setTurnGunRight( Double.POSITIVE_INFINITY);
setTurnRadarLeft( Double.POSITIVE_INFINITY);
setTurnRight?(10);
ahead(10);
waitFor(new RadarTurnCompleteCondition?(this));

Removed: 154d159


Changed: 157c162
return 20 - 3 * power;
return 20 - 3 * power;

Changed: 161,162c166,167
return new Point2D.Double(sourceLocation.getX() + Math.sin(angle) * length,
sourceLocation.getY() + Math.cos(angle) * length);
return new Point2D.Double(sourceLocation.getX() + Math.sin(angle) * length,
sourceLocation.getY() + Math.cos(angle) * length);

Changed: 166,175c171
return Math.atan2(target.getX() - source.getX(), target.getY() - source.getY());
}

static int wallIndex(Wave wave, double direction) {
int wallIndex = 0;
do {
wallIndex++;
} while (wallIndex < (WALL_INDEXES) &&
fireField.contains(project(wave.wGunLocation?, wave.wBearing + direction * wave.wBearingDirection? * (double)(wallIndex * 7.5), enemyDistance)));
return wallIndex - 1;
return Math.atan2(target.getX() - source.getX(), target.getY() - source.getY());

Changed: 179,197c175,193
double wBulletPower?;
Point2D wGunLocation?;
double wBearing;
double wBearingDirection?;
int[] wAimFactors?;
double wDistance;

public boolean test() {
if ((wDistance += bulletVelocity(wBulletPower?)) > wGunLocation?.distance(enemyLocation) - 18) {
try {
wAimFactors?[(int)Math.round(((Utils.normalRelativeAngle(absoluteBearing(wGunLocation?, enemyLocation) - wBearing)) /
wBearingDirection?) + MIDDLE_FACTOR)]++;
}
catch (Exception e) {
}
removeCustomEvent(this);
}
return false;
}
double wBulletPower?;
Point2D wGunLocation?;
double wBearing;
double wBearingDirection?;
int[] wAimFactors?;
double wDistance;

public boolean test() {
if ((wDistance += bulletVelocity(wBulletPower?)) > wGunLocation?.distance(enemyLocation) - 18) {
try {
wAimFactors?[(int)Math.round(((Utils.normalRelativeAngle(absoluteBearing(wGunLocation?, enemyLocation) - wBearing)) /
wBearingDirection?) + MIDDLE_FACTOR)]++;
}
catch (Exception e) {
}
removeCustomEvent(this);
}
return false;
}

Changed: 215c211,216
It might. But to me it looks like most of the fight is carried at point blank. And then the circular prediction is 100% right while even one wrong guess from the learning gun will lower performance. (I've seen ARAMtocles miss while it looks to be ramming the opponent... The guns start heated so during the time it takes for the rammer to close in it can't fire anyway. Mayvbe I even should consider using linear or circular predictions in CassiusClay when I know I am dealing with a rammer. -- PEZ
It might. But to me it looks like most of the fight is carried at point blank. And then the circular prediction is 100% right while even one wrong guess from the learning gun will lower performance. (I've seen ARAMtocles miss while it looks to be ramming the opponent... The guns start heated so during the time it takes for the rammer to close in it can't fire anyway. Mayvbe I even should consider using linear or circular predictions in CassiusClay when I know I am dealing with a rammer. -- PEZ

The newest version basically goes back to v0.1, but with improved distance segmenting and bulletpower. It should at least end up around rating 1615. Further development (if any) will be done with the RambotChallenge2K6. A specialized GF-gun should be able to handle short rammer matches. -- GrubbmGait

I should not fiddle with things I know nothing about. In my tests over 500 rounds ARAMtocles 0.3 humiliates every other rambot, but over 35 rounds it gets kicked in the butt. Till now CircularTargeting seems unbeatable at close ranges. -- GrubbmGait


ARAMtocles

By GrubbmGait and PEZ

What is it?

A MicroBot. The result of using Aristocles's gun on the mean RamBot GrubbmThree

It can be found here: http://www.robocoderepository.com/BotDetail.jsp?id=2864

History

Code

RWPCL applies.

package wiki.micro;
import robocode.*;
import robocode.util.Utils;
import java.awt.Color;
import java.awt.geom.*;
/**
 * ARAMtocles - ramming with GuessFactors
 * Gunnery of Aristocles by PEZ
 * rest of GrubbmThree by GrubbmGait (but that turns out to be very little)
 * RWPCL applies
 *
 * Revision information:
 * v0.1 20060213 Initial version, shrunk GrubbmThree and GF-gun of Aristocles.
 *               No tuning of segmentation. 726 bytes
 * v0.2 20060213 Added reverse wall segmentation. Lowered the granularity in general to 
 *               accomodate to the short learning times ramming gives you. 732 bytes
 * v0.3 20060217 Removed reverse wall stuff.
 *               Rearranged distance segmentation and bulletpower. 707 bytes
 */
public class ARAMtocles extends AdvancedRobot
{
    static final double MAX_DISTANCE = 450;
    static final double BULLET_SWITCH_DISTANCE = 180;
    static final double MAX_BULLET_POWER = 3.0;       // first two distance segments
    static final double BULLET_POWER = 1.9;           // third and fourth distance segment
    static final double WALL_MARGIN = 18;

    static final int DISTANCE_INDEXES = 5;
    static final int VELOCITY_INDEXES = 5;
    static final int LAST_VELOCITY_INDEXES = 5;
    static final int WALL_INDEXES = 2;
    static final int DECCEL_TIME_INDEXES = 5;
    static final int AIM_FACTORS = 25;
    static final int MIDDLE_FACTOR = (AIM_FACTORS - 1) / 2;

    static Rectangle2D.Double fireField;    // the shootable battlefield
    static Point2D enemyLocation;
    static double enemyVelocity;
    static int timeSinceDeccel;
    static double bearingDirection;
    static double enemyDistance;
    static int[][][][][][] aimFactors = new int[DISTANCE_INDEXES][VELOCITY_INDEXES][LAST_VELOCITY_INDEXES][DECCEL_TIME_INDEXES][WALL_INDEXES][AIM_FACTORS];

    /**
     * run: ARAMtocles default behavior
     */
    public void run() {

        setColors( Color.red, Color.blue, Color.yellow);

        fireField = new Rectangle2D.Double( WALL_MARGIN, WALL_MARGIN, getBattleFieldWidth() - WALL_MARGIN * 2, getBattleFieldHeight() - WALL_MARGIN * 2);

        // Let gun and radar move independently
        setAdjustGunForRobotTurn( true);
        setAdjustRadarForGunTurn( true);

        // mainloop
        do {
            turnRadarRight( Double.NEGATIVE_INFINITY);
        } while(true);
    }

    /**
     * onScannedRobot: What to do when you see another robot
     */
    public void onScannedRobot(ScannedRobotEvent e) {

        double tmpbearing = getHeadingRadians() + e.getBearingRadians();
        double turnAngle;

        // Lock target with radar
        setTurnRadarRightRadians( 2.2 * Utils.normalRelativeAngle( tmpbearing - getRadarHeadingRadians()));

        // perform Aristocles targeting
        Wave wave = new Wave();
        double enemyAbsoluteBearing = getHeadingRadians() + e.getBearingRadians();
        enemyLocation = project(wave.wGunLocation = new Point2D.Double(getX(), getY()), enemyAbsoluteBearing, enemyDistance = e.getDistance());

        int lastVelocityIndex = (int)Math.abs(enemyVelocity) / 2;
        int velocityIndex = (int)Math.abs((enemyVelocity = e.getVelocity()) / 2);
        if (velocityIndex < lastVelocityIndex) {
            timeSinceDeccel = 0;
        }

        if (enemyVelocity != 0) {
            bearingDirection = enemyVelocity * Math.sin(e.getHeadingRadians() - enemyAbsoluteBearing) > 0 ?
            0.7 / (double)MIDDLE_FACTOR : -0.7 / (double)MIDDLE_FACTOR;
        }
        wave.wBearingDirection = bearingDirection;

        int distanceIndex = (int)Math.min(DISTANCE_INDEXES - 1, enemyDistance / (MAX_DISTANCE / DISTANCE_INDEXES));
        wave.wBulletPower = enemyDistance > BULLET_SWITCH_DISTANCE ? BULLET_POWER : MAX_BULLET_POWER;
        //wave.wBulletPower = MAX_BULLET_POWER; // TargetingChallenge

        wave.wAimFactors = aimFactors[distanceIndex][velocityIndex][lastVelocityIndex][Math.min(DECCEL_TIME_INDEXES - 1, timeSinceDeccel++ / 13)]
            [fireField.contains(project(wave.wGunLocation, enemyAbsoluteBearing + wave.wBearingDirection * 13, enemyDistance)) ? 1 : 0];

        wave.wBearing = enemyAbsoluteBearing;

        int mostVisited = MIDDLE_FACTOR, i = AIM_FACTORS;
        do  {
            if (wave.wAimFactors[--i] > wave.wAimFactors[mostVisited]) {
                mostVisited = i;
            }
        } while (i > 0);
        // end of Aristocles gun

        // Turn gun (still Aristocles, but keep tmpbearing for movement)
        tmpbearing = enemyAbsoluteBearing + wave.wBearingDirection * (mostVisited - MIDDLE_FACTOR);
        setTurnGunRightRadians( Utils.normalRelativeAngle( tmpbearing - getGunHeadingRadians()));

        if (enemyDistance <= (2 * BULLET_SWITCH_DISTANCE)) {
            setFire(wave.wBulletPower);
        }
        // Aristocles
        if (getEnergy() >= BULLET_POWER) {
            addCustomEvent(wave);
        }
        // GT: Move towards target
        turnAngle = Utils.normalRelativeAngle( tmpbearing - getHeadingRadians());
        setTurnRightRadians( Math.atan( Math.tan( turnAngle)));
        setAhead( Double.POSITIVE_INFINITY * Math.cos( turnAngle));
    }


    /**
     * onWin: Show my private victory dance
     */
    public void onWin(WinEvent e)
    {
        //Victory dance
        setTurnGunRight( Double.POSITIVE_INFINITY);
        setTurnRadarLeft( Double.POSITIVE_INFINITY);
        setTurnRight(10);
        ahead(10);
        waitFor(new RadarTurnCompleteCondition(this));
    }

    // Aristocles: helperfunctions and so
    static double bulletVelocity(double power) {
        return 20 - 3 * power;
    }

    static Point2D project(Point2D sourceLocation, double angle, double length) {
        return new Point2D.Double(sourceLocation.getX() + Math.sin(angle) * length,
            sourceLocation.getY() + Math.cos(angle) * length);
    }

    static double absoluteBearing(Point2D source, Point2D target) {
        return Math.atan2(target.getX() - source.getX(), target.getY() - source.getY());
    }

    class Wave extends Condition {
    double wBulletPower;
    Point2D wGunLocation;
    double wBearing;
    double wBearingDirection;
    int[] wAimFactors;
    double wDistance;

    public boolean test() {
        if ((wDistance += bulletVelocity(wBulletPower)) > wGunLocation.distance(enemyLocation) - 18) {
        try {
            wAimFactors[(int)Math.round(((Utils.normalRelativeAngle(absoluteBearing(wGunLocation, enemyLocation) - wBearing)) /
                wBearingDirection) + MIDDLE_FACTOR)]++;
        }
        catch (Exception e) {
        }
        removeCustomEvent(this);
        }
        return false;
    }
    }
}

Comments

Grub, I've tried to tune the segmentations some. Mainly it was about narrowing down the distance segmentation and also using less granularity. (There's not much time to learn during a ram fight.) I also added a reverse wall segmentation, which I am not sure it helps much now that I have watched a few fights with this bot. But anyway. Can you pack this up and release on the rumble for test? -- PEZ

Its up, lets see if can do some more damage. -- GrubbmGait

Again it doesn't look too promising. It could be something is buggy with the gun now, but probably it just means the gun just isn't cut for dealing with the extreme fast learning needed here. And at those fighting distances the circular targeting might just be better than bothering with stats. -- PEZ

I think you are right, each battle only lasts between 100 and 200 ticks, so there is almost no time for learning. I expected ARAMtocles to be an improvement against the better anti-rammers as running away seems quite predictable, but it seems that that can not compensate the lesser performance in the first rounds. -- GrubbmGait

This is a bit dissapointing, but I can't make this work even with low segmentation it seems. Poor ARAM seems to be a poor rammer compared to its ancestor and cousin. I say we remove it from the rumble until we have some more ideas on how to make it work. -- PEZ

PEZ, maybe an advancing velocity segment would be useful in this bot? It seems that a rammer might create exploitable behaviour in that dimension (since the enemy will most likely be moving away from you). Just a thought. --wcsv

It might. But to me it looks like most of the fight is carried at point blank. And then the circular prediction is 100% right while even one wrong guess from the learning gun will lower performance. (I've seen ARAMtocles miss while it looks to be ramming the opponent... The guns start heated so during the time it takes for the rammer to close in it can't fire anyway. Mayvbe I even should consider using linear or circular predictions in CassiusClay when I know I am dealing with a rammer. -- PEZ

The newest version basically goes back to v0.1, but with improved distance segmenting and bulletpower. It should at least end up around rating 1615. Further development (if any) will be done with the RambotChallenge2K6. A specialized GF-gun should be able to handle short rammer matches. -- GrubbmGait

I should not fiddle with things I know nothing about. In my tests over 500 rounds ARAMtocles 0.3 humiliates every other rambot, but over 35 rounds it gets kicked in the butt. Till now CircularTargeting seems unbeatable at close ranges. -- GrubbmGait


Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited February 20, 2006 11:37 EST by GrubbmGait (diff)
Search: