User:Rednaxela/BotBase
Jump to navigation
Jump to search
This is a class I've been basing all of my recent non-codesize-restricted bots off of.
Contents
BotBase.java
package ags.muse.base; import ags.muse.base.actors.*; import java.awt.Color; import java.awt.Graphics2D; import java.util.ArrayList; import java.util.List; import robocode.BulletHitBulletEvent; import robocode.BulletHitEvent; import robocode.BulletMissedEvent; import robocode.CustomEvent; import robocode.DeathEvent; import robocode.Event; import robocode.HitByBulletEvent; import robocode.HitRobotEvent; import robocode.HitWallEvent; import robocode.MessageEvent; import robocode.RobotDeathEvent; import robocode.ScannedRobotEvent; import robocode.SkippedTurnEvent; import robocode.StatusEvent; import robocode.WinEvent; import robocode.TeamRobot; /** * @author Alexander Schultz */ abstract public class BotBase extends TeamRobot { private Rules rules; private GunActor gunActor; private MovementActor movementActor; private RadarActor radarActor; private BroadcastActor broadcastActor; public Rules getRules() { return rules; } public GunActor getGunActor() { return gunActor; } public MovementActor getMovementActor() { return movementActor; } public RadarActor getRadarActor() { return radarActor; } public BroadcastActor getBroadcastActor() { return broadcastActor; } private final List<Event> events = new ArrayList<Event>(); private List<Event> getEvents() { List<Event> output = new ArrayList<Event>(events); events.clear(); return output; } public void onCustomEvent(CustomEvent arg0) { events.add(arg0); } public void onMessageReceived(MessageEvent arg0) { events.add(arg0); } public void onBulletHit(BulletHitEvent arg0) { events.add(arg0); } public void onBulletHitBullet(BulletHitBulletEvent arg0) { events.add(arg0); } public void onBulletMissed(BulletMissedEvent arg0) { events.add(arg0); } public void onDeath(DeathEvent arg0) { events.add(arg0); } public void onHitByBullet(HitByBulletEvent arg0) { events.add(arg0); } public void onHitRobot(HitRobotEvent arg0) { events.add(arg0); } public void onHitWall(HitWallEvent arg0) { events.add(arg0); } public void onRobotDeath(RobotDeathEvent arg0) { events.add(arg0); } public void onScannedRobot(ScannedRobotEvent arg0) { events.add(arg0); } public void onStatus(StatusEvent arg0) { events.add(arg0); } public void onWin(WinEvent arg0) { events.add(arg0); } public void onSkippedTurn(SkippedTurnEvent arg0) { events.add(arg0); System.out.println("Warning! Turn skipped!"); } // Echo broadcast messages back to self @Override public void broadcastMessage(java.io.Serializable s) throws java.io.IOException { super.broadcastMessage(s); events.add(new MessageEvent(rules.NAME, s)); } public void setColors(final Color bodyColor, final Color scanColor, final Color gunColor, final Color radarColor) { if (!running) throw new UnsupportedOperationException("Bot must be running before colors may be set."); this.setBodyColor(bodyColor); this.setScanColor(scanColor); this.setGunColor(gunColor); this.setRadarColor(radarColor); } abstract public void init(); abstract public void runTick(List<Event> events); abstract public void _onPaint(Graphics2D g); private final void preInit() { // Set turning to be independent this.setAdjustGunForRobotTurn(true); this.setAdjustRadarForRobotTurn(true); this.setAdjustRadarForGunTurn(true); // Set up rules class rules = new Rules(this); // Start up staticsaver StaticSaver.init(this); // Set up actors gunActor = new GunActor(this); movementActor = new MovementActor(this); radarActor = new RadarActor(this); broadcastActor = new BroadcastActor(this); } private void ensureVersion() { if (getTime() < 2) { boolean gotstatus = false; for (Event event : events) { if (event instanceof robocode.StatusEvent) gotstatus = true; if (event instanceof robocode.DeathEvent) gotstatus = true; if (event instanceof robocode.WinEvent) gotstatus = true; } // If we didn't get a StatusEvent DeathEvent, or WinEvent something is wrong... (i.e. very old robocode version) if (!gotstatus) { System.out.println("Got no status event! Dying now! :("); while (true); } } } private boolean running = false; @Override public void run() { if (running) throw new UnsupportedOperationException("Main loop already running!"); running = true; preInit(); init(); while(true) { if (events.size() != 0) { ensureVersion(); runTick(getEvents()); } execute(); } } @Override public void onPaint(Graphics2D g) { if (events.size() != 0) { ensureVersion(); runTick(getEvents()); } _onPaint(g); } }
Rules.java
package ags.muse.base; import robocode.TeamRobot; /** * A consoladated "Rules" class, which includes gun cooling rate, field size, * teammate listings, and always uses radians. * * Essentially stores all battle information that is known from the very start * of the battle that does not change. * * @author Alexander Schultz */ public class Rules { // Redirection to robocode.Rules public final double ACCELERATION = robocode.Rules.ACCELERATION; public final double DECELERATION = robocode.Rules.DECELERATION; public final double GUN_TURN_RATE = robocode.Rules.GUN_TURN_RATE_RADIANS; public final double MAX_BULLET_POWER = robocode.Rules.MAX_BULLET_POWER; public final double MAX_TURN_RATE = robocode.Rules.MAX_TURN_RATE_RADIANS; public final double MAX_VELOCITY = robocode.Rules.MAX_VELOCITY; public final double MIN_BULLET_POWER = robocode.Rules.MIN_BULLET_POWER; public final double RADAR_SCAN_RADIUS = robocode.Rules.RADAR_SCAN_RADIUS; public final double RADAR_TURN_RATE = robocode.Rules.RADAR_TURN_RATE_RADIANS; public final double ROBOT_HIT_BONUS = robocode.Rules.ROBOT_HIT_BONUS; public final double ROBOT_HIT_DAMAGE = robocode.Rules.ROBOT_HIT_DAMAGE; public double getBulletDamage(double bulletPower) { return robocode.Rules.getBulletDamage(bulletPower); } public double getBulletHitBonus(double bulletPower) { return robocode.Rules.getBulletHitBonus(bulletPower); } public double getBulletSpeed(double bulletPower) { return robocode.Rules.getBulletSpeed(bulletPower); } public double getGunHeat(double bulletPower) { return robocode.Rules.getGunHeat(bulletPower); } public double getTurnRate(double velocity) { return robocode.Rules.getTurnRateRadians(velocity); } public double getWallHitDamage(double velocity) { return robocode.Rules.getWallHitDamage(velocity); } // New features public final double GUN_COOLING_RATE; public final double BATTLEFIELD_WIDTH; public final double BATTLEFIELD_HEIGHT; public final String[] TEAMMATES; public final int ENEMIES; public final String NAME; public Rules(TeamRobot peer) { GUN_COOLING_RATE = peer.getGunCoolingRate(); BATTLEFIELD_WIDTH = peer.getBattleFieldWidth(); BATTLEFIELD_HEIGHT = peer.getBattleFieldHeight(); if (peer.getTeammates() != null) TEAMMATES = peer.getTeammates(); else TEAMMATES = new String[0]; NAME = peer.getName(); ENEMIES = peer.getOthers()-TEAMMATES.length; } public boolean isTeammate(String name) { if (TEAMMATES == null) return false; for (String teammate : TEAMMATES) { if (teammate.equals(name)) return true; } return false; } public double damageToBulletPower(double energy) { if (energy/4 <= 1) return energy/4; else return (energy+2)/6; } public double getHitRegneration(double bulletPower) { return 3*bulletPower; } }
StaticSaver.java
package ags.muse.base; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import robocode.AdvancedRobot; import robocode.RobocodeFileOutputStream; public class StaticSaver { private static File dataDirectory; public static void init(AdvancedRobot bot) { dataDirectory = bot.getDataDirectory(); System.out.println("Bot data directory:"); System.out.print("\t"); System.out.println(dataDirectory.getAbsolutePath()); } public static RobocodeFileOutputStream getOutputFile(String filename, boolean append) throws IOException { if (dataDirectory == null) throw new java.lang.IllegalStateException(); File file = new File(dataDirectory, filename); RobocodeFileOutputStream fileWriter = new RobocodeFileOutputStream(file.getPath(), append); return fileWriter; } public static FileInputStream getInputFile(String filename) throws IOException { if (dataDirectory == null) throw new java.lang.IllegalStateException(); File file = new File(dataDirectory, filename); return new FileInputStream(file); } }
BroadcastActor.java
package ags.muse.base.actors; import robocode.TeamRobot; public class BroadcastActor { private final TeamRobot peer; public BroadcastActor(TeamRobot peer) { this.peer = peer; } public void broadcastMessage(java.io.Serializable s) { try { peer.broadcastMessage(s); } catch (java.io.IOException e) { System.out.println("Error during sending team message!"); e.printStackTrace(); } } }
GunActor.java
package ags.muse.base.actors; import robocode.Bullet; import robocode.TeamRobot; public class GunActor { private final TeamRobot peer; public GunActor(TeamRobot peer) { this.peer = peer; } public Bullet setFire(double arg0) { return peer.setFireBullet(arg0); } public void setTurnGun(double arg0) { peer.setTurnGunRightRadians(arg0); } }
MovementActor.java
package ags.muse.base.actors; import robocode.TeamRobot; public class MovementActor { private final TeamRobot peer; public MovementActor(TeamRobot peer) { this.peer = peer; } public void setMove(double velocity) { setMove(velocity, velocity==0 ? 0 : (velocity > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY)); } public void setMove(double velocity, double dist) { peer.setMaxVelocity(Math.abs(velocity)); peer.setAhead(dist); } public void setTurnBody(double arg0) { peer.setTurnRightRadians(arg0); } }
RadarActor.java
package ags.muse.base.actors; import robocode.TeamRobot; public class RadarActor { private final TeamRobot peer; public RadarActor(TeamRobot peer) { this.peer = peer; } public void setTurnRadar(double arg0) { peer.setTurnRadarRightRadians(arg0); } }