/** * RampantRobot.java */ package rampancy; import rampancy.util.*; import rampancy.util.movement.RMoveChoice; import rampancy.util.wave.*; import rampancy.util.weapon.RFiringSolution; import robocode.AdvancedRobot; import robocode.BattleEndedEvent; import robocode.Bullet; import robocode.BulletHitBulletEvent; import robocode.BulletHitEvent; import robocode.HitByBulletEvent; import robocode.ScannedRobotEvent; import robocode.util.Utils; import java.awt.*; import java.awt.event.KeyEvent; import java.util.*; /** * @author Matthew Chun-Lum * */ public abstract class RampantRobot extends AdvancedRobot { public static final int MAX_HISTORY_DEPTH = 1000; public static RBattlefield globalBattlefield; public static REnemyManager enemyManager; public static RWaveManager waveManager; public static RMovementManager movementManager; public static RTargetingManager targetingManager; public static RStatisticsManager statisticsManager; // /** // * @return a reference to the RampantRobot // */ // public static RampantRobot getGlobalReference() { // return globalReference; // } /** * @return a reference to the Battlefield */ public static RBattlefield getGlobalBattlefield() { return globalBattlefield; } /* * Static wrappers for managers */ public static REnemyManager getEnemyManager() { return enemyManager; } public static RWaveManager getWaveManager() { return waveManager; } public static RMovementManager getMovementManager() { return movementManager; } public static RTargetingManager getTargetingManager() { return targetingManager; } public static RStatisticsManager getStatisticsManager() { return statisticsManager; } protected static boolean drawMovement = true; protected static boolean drawGun = true; protected static boolean drawWaves = true; protected static boolean drawEnemy = true; protected RPoint location; protected LinkedList<RRobotState> states; protected String lastType; protected long fireTime = 0; protected long ticksSinceLastVirtualBullet = 0; protected boolean processingShot; protected RFiringSolution lockedSolution; protected REnemyRobot lockedEnemy; public RampantRobot() { super(); states = new LinkedList<RRobotState>(); lastType = ""; } public void run() { super.run(); setAdjustGunForRobotTurn(true); setAdjustRadarForGunTurn(true); setAdjustRadarForRobotTurn(true); globalBattlefield = new RBattlefield((int) getBattleFieldWidth(), (int) getBattleFieldHeight()); } public void onScannedRobot(ScannedRobotEvent e) { updateState(e); REnemyRobot enemy = enemyManager.findOrCreateByName(e.getName()); if(enemy != null) { // update the state of the scanned enemy enemy.update(e); // update all of our waves waveManager.update(); // move in the best way possible // (as determined by the manager) RMoveChoice choice = movementManager.computeBestMove(enemy); if(choice != null) RUtil.setBackAsFront(this, choice.angle, 100); // target the enemy robot ArrayList<RFiringSolution> firingSolutions = new ArrayList<RFiringSolution>(targetingManager.getBestFiringSolutions(enemy)); if(!firingSolutions.isEmpty()) { lockFiringSolution(enemy, firingSolutions.get(0)); simulateRemainingSolutions(enemy, firingSolutions); } else if(!processingShot) { turnGunToTarget(enemy); } if(attemptShot()) { processingShot = false; } //attemptToShoot(enemy, firingSolution); } } public void onHitByBullet(HitByBulletEvent e) { Bullet bullet = e.getBullet(); REnemyWave wave = waveManager.getWaveForEnemyBullet(bullet); if(wave != null) { RPoint hitLocation = new RPoint(bullet.getX(), bullet.getY()); statisticsManager.getMovementStatistics().noteHitByBullet(wave, hitLocation); } } public void onBulletHitBullet(BulletHitBulletEvent e){ Bullet bullet = e.getBullet(); REnemyWave wave = waveManager.getWaveForEnemyBullet(bullet); if(wave != null) { RPoint hitLocation = new RPoint(bullet.getX(), bullet.getY()); statisticsManager.getMovementStatistics().noteHitByBullet(wave, hitLocation); } } public void onBulletHit(BulletHitEvent e) { Bullet bullet = e.getBullet(); REnemyRobot enemy = enemyManager.get(e.getName()); if(enemy == null) return; RBulletWave wave = waveManager.getWaveForBullet(bullet); if(wave == null) { return; } if(!enemy.getName().equalsIgnoreCase(wave.getTarget().getName())) return; } public void onBattleEnded(BattleEndedEvent e) { } public void onKeyTyped(KeyEvent e) { int key = e.getKeyChar(); switch(key) { case 'w': drawWaves = !drawWaves; break; case 'e': drawEnemy = !drawEnemy; break; case 'g': drawGun = !drawGun; break; case 'm': drawMovement = !drawMovement; break; } } public void updateState(ScannedRobotEvent e) { states.push(new RRobotState(this, e)); if(states.size() > MAX_HISTORY_DEPTH) states.removeLast(); } /** * @return the current state */ public RRobotState getCurrentState() { if(states.isEmpty()) return null; return states.get(0); } /** * @return the last state of the robot */ public RRobotState getLastState() { if(states.isEmpty()) return getCurrentState(); return states.getFirst(); } /** * @return the last usable state of the RampantRobot */ public RRobotState getLastUsableState() { if(states.size() < 3) return getLastState(); return states.get(2); } /** * @return a reference to the robot's location */ public RPoint getLocation() { RRobotState state = getCurrentState(); if(state == null || state.location == null) return new RPoint(getX(), getY()); return state.location.getCopy(); } /** * @return a copy of the robot's location */ public RPoint getCopyOfLocation() { return getLocation().getCopy(); } /* (non-Javadoc) * @see robocode.Robot#onPaint(java.awt.Graphics2D) */ public void onPaint(Graphics2D g) { if(globalBattlefield != null) globalBattlefield.draw(g); if(enemyManager != null && drawEnemy) enemyManager.draw(g); if(waveManager != null && drawWaves) waveManager.draw(g); if(movementManager != null && drawMovement) movementManager.draw(g); } protected boolean attemptShot() { if(!processingShot) { return false; } if(fireTime <= getTime() && getGunTurnRemainingRadians() == 0) { if(lockedSolution.intendedHitLocation != null) { double distance = getLocation().distance(lockedSolution.intendedHitLocation); double desiredVelocity = distance / (lockedSolution.anticipatedFlightTime - 1); lockedSolution.power = RUtil.computeBulletPower(desiredVelocity); } if(setFireBullet(lockedSolution.power) != null) { RBulletWave wave = new RBulletWave(lockedEnemy, lockedSolution, false); lockedSolution.gun.noteShot(true); waveManager.add(wave); if(true || !lockedSolution.gun.getName().equals(lastType)) { lastType = lockedSolution.gun.getName(); //System.out.println("Using " + lastType + "\nwith gf " + lockedSolution.guessFactor + "\nwith reliability " + lockedSolution.reliabilityFactor); } } return true; } return false; } protected boolean lockFiringSolution(REnemyRobot enemy, RFiringSolution firingSolution) { if(!processingShot) { lockedEnemy = enemy; lockedSolution = firingSolution; setTurnGunRightRadians(Utils.normalRelativeAngle(lockedSolution.firingAngle)); fireTime = getTime() + 1; processingShot = true; return true; } return false; } protected void simulateRemainingSolutions(REnemyRobot enemy, ArrayList<RFiringSolution> firingSolutions) { if(getGunHeat() == 0 && getEnergy() != 0) { int i = 1; for(; i < firingSolutions.size(); i++) { RBulletWave wave = new RBulletWave(enemy, firingSolutions.get(i), true); firingSolutions.get(i).gun.noteShot(false); waveManager.add(wave); } } } protected void turnGunToTarget(REnemyRobot enemy) { RRobotState enemyState = enemy.getCurrentState(); double gunBearingToTarget = enemyState.absoluteBearing - getGunHeadingRadians(); gunBearingToTarget = Utils.normalRelativeAngle(gunBearingToTarget); setTurnGunRightRadians(gunBearingToTarget); } }