TajBot (Robocode bot)

Copyright Tristan Aubrey-Jones December 2005.

TajBot.java

home Home   up Up   ( Download )


package tajy; import robocode.*; import java.awt.Color; import java.util.HashMap; import java.util.Iterator; /** * TajBot - a robot by (your name here) */ public class TajBot extends AdvancedRobot { private HashMap targets; private boolean forward = true; public double aimBearing = 0; private MoveCompleteCondition moveComplete; private RadarTurnCompleteCondition radarComplete; private Enemy currentTarget; private double energy = 1; // energy to fire with private long lastSweep = 0; // time of last 360 sweep private final long sweepDelay = 20; // 360 sweep every half second private long holdFireTil = -1; // dont fire til this time private double ratio = 1; // hit ratio private final double aimAccuracy = 1; // accuracy in degrees /** * run: TajBot's default behavior */ public void run() { // init setColors(Color.red,Color.blue,Color.green); targets = new HashMap(); //setAdjustGunForRobotTurn(true); moveComplete = new MoveCompleteCondition(this); radarComplete = new RadarTurnCompleteCondition(this); turnRadarRight(360); ahead(10); // run while (true) { attack(); } } private Enemy getEnemy(String name) { return (Enemy)targets.get(name); } public Vector getPosition() { return new Vector(getX(), getY()); } private Enemy getBestTarget() { double maxThreat = 0; Enemy target = null; for (Iterator i = targets.values().iterator(); i.hasNext(); ) { Enemy enemy = (Enemy)i.next(); double threat = enemy.getPriority(); if ((enemy == null) || (threat > maxThreat)) { target = enemy; maxThreat = threat; } } if (currentTarget != null) currentTarget.setTargeted(false); currentTarget = target; if (currentTarget != null) currentTarget.setTargeted(true); return target; } private Enemy getWorstThreat() { double maxThreat = 0; Enemy target = null; for (Iterator i = targets.values().iterator(); i.hasNext(); ) { Enemy enemy = (Enemy)i.next(); double threat = enemy.getThreat(); if ((enemy == null) || (threat > maxThreat)) { target = enemy; maxThreat = threat; } } return target; } private void attack() { // get current threat Vector m = getPosition(); Enemy target = getBestTarget(); if (target != null) { ratio = target.hitRatio(); // big energy when point blank energy = 1; if ((target.getVelocity() < 1) || (target.getDistance(m) < 200)) energy = 3; // aim double targetBearing = aimAtTarget(target); if ((target.getDistance(m) > 400) || (target.hitRatio() < 0.3)) { // make sure am face on to robot double turnRight = targetBearing - getHeading(); if (turnRight < 180) setTurnRight(turnRight); else setTurnLeft(360 - turnRight); // move in closer setAhead(20); } else { // low energy so dont waste bullets if (target.hitRatio() < 1) { energy = target.hitRatio(); } // calculate threat bearing Enemy threat = getWorstThreat(); Vector t = threat.getPosition(); double threatBearing = BotMaths.getAimBearing(getPosition(), t); // make sure am side on to target double robotBearing = threatBearing + 90; double turnRight = robotBearing - getHeading(); if (turnRight < 180) setTurnRight(turnRight); else setTurnLeft(360 - turnRight); // strife if (moveComplete.test()) { if (forward) { setAhead(200); forward = false; } else { setBack(200); forward = true; } } } // fire (if aiming correctly) if ((getGunHeading() > targetBearing - aimAccuracy) && (getGunHeading() < targetBearing + aimAccuracy)) { if (getGunHeat() == 0) { this.waitFor(new GunTurnCompleteCondition(this)); if (holdFireTil == -1) setFire(energy); else { if (getTime() >= holdFireTil) { holdFireTil = -1; setFire(energy); } } } } //else out.println("Dont shoot."); } // execute actions execute(); } private Vector averageEnemyPosition() { Vector sum = new Vector(0, 0); for (Iterator i = targets.values().iterator(); i.hasNext(); ) { Enemy enemy = (Enemy)i.next(); sum = sum.add(enemy.getPosition()); } double x = sum.getX() / targets.size(); double y = sum.getY() / targets.size(); return new Vector(x, y); } private double getQuietBearing() { Vector enemyPosition = averageEnemyPosition(); double bearing = BotMaths.getAimBearing(getPosition(), enemyPosition); return (bearing + 180) % 360; } private double aimAtTarget(Enemy target) { // target vector Vector t = null; // target occilates about a point /*if (t == null) { // see if target is occilating about a point CycleSpotter c = target.getPatternWatcher(); int i = c.getBestTarget(getPosition()); int hits = c.getVisits(i); // if good point if (hits > 3) { energy = 3; t = c.getPosition(i); long bulletDelay = (long)BotMaths.getBulletTime(t.distanceTo(getPosition()), energy); long nextFire = c.getNextTime(i, getTime() - bulletDelay); if (nextFire < 100) { out.println("Occilating."); holdFireTil = nextFire; } else t = null; } }*/ // no obvious pattern to movement if (t == null) { // estimate position of robot when bullet hits //out.println("Anticipating."); energy = 1.5; // iterate estimating target coord. t = target.getPosition(); double delay = 0; for (int i = 0; i != 5; i++) { delay = getTime() + BotMaths.getBulletTime(t.distanceTo(getPosition()), energy); t = BotMaths.estimateTargetCoord(target.getPosition(), target.getHeading(), target.getTimeSinceScan(delay)); } delay -= 3; t = BotMaths.estimateTargetCoord(target.getPosition(), target.getHeading(), target.getTimeSinceScan(delay)); // will they hit a wall? if ((t.getX() < 0) || (t.getX() > getBattleFieldWidth()) || (t.getY() < 0) || (t.getY() > getBattleFieldHeight())) { t = null; energy = 0.1; } } // default to last scanned local if (t == null) { energy = 0.8; t = target.getPosition(); } // if point blank if (getEnergy() < 10) energy = 0.1; // if point blank if (target.getPosition().distanceTo(getPosition()) < 200) { energy = 1.5; } // if point blank if (target.getPosition().distanceTo(getPosition()) < 100) { energy = 3; } // calculate bearing of anticipated location double targetBearing = BotMaths.getAimBearing(getPosition(), t); double angle = targetBearing - getGunHeading(); aimBearing = angle; // scanning... if (radarComplete.test()) { if (lastSweep + sweepDelay < getTime()) { setTurnRadarRight(360); lastSweep = getTime(); } else { // scan target double radarAngle = targetBearing - getRadarHeading(); if (radarAngle > 0) { setTurnRadarRight(radarAngle + 20); } else { setTurnRadarLeft(20 - radarAngle); } } } // aim at location if (angle < 180) { setTurnGunRight(angle); } else if (angle > 180) { setTurnGunLeft(360 - angle); } return targetBearing; } public void setTurnGunRight(double d) { if (d >= 180) { out.print(d); out.println(" right."); } super.setTurnGunRight(d); } public void setTurnGunLeft(double d) { if (d >= 180) { out.print(d); out.println(" left."); } super.setTurnGunLeft(d); } /** * onScannedRobot: What to do when you see another robot */ public void onScannedRobot(ScannedRobotEvent e) { // add target to table String name = e.getName(); if (!targets.containsKey(name)) { targets.put(name, new Enemy(name)); } // update target scan Enemy target = getEnemy(name); target.scanned(e, this); } public void onBulletHit(BulletHitEvent event) { // register shot Enemy target = getEnemy(event.getName()); if (target != null) target.gotHim(); } public void onBulletMissed(BulletMissedEvent event) { // register shot if (currentTarget != null) currentTarget.missedHim(); } public void onRobotDeath(RobotDeathEvent event) { targets.remove(event.getName()); } /** * onHitByBullet: What to do when you're hit by a bullet */ public void onHitByBullet(HitByBulletEvent e) { // register shot Enemy target = getEnemy(e.getName()); if (target != null) target.shotMe(this); } public void onHitRobot(HitRobotEvent event) { Enemy target = getEnemy(event.getName()); if (target != null) { target.hit(event, this); } } public void onHitWall(HitWallEvent event) { //setTurnRight(90); //setAhead(100); } public void onWin(WinEvent e) { out.println(ratio); } }