Shrinking OculusMicro
The highlighted comment was created in this revision.
The package is dsekercioglu.micro but it is a mini(856 bytes) right now. I am not very good at shrinking so can somebody help me please? Thank you.
package dsekercioglu.micro;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import robocode.Condition;
import robocode.Rules;
import static robocode.util.Utils.normalRelativeAngle;
public class OculusMicro extends robocode.AdvancedRobot {
static float[][] statistics = new float[5][31];
static double enemyEnergy = 100;
static double oldLatVel = 0;
static Point2D.Double myLocation;
static Rectangle2D.Double battleField = new Rectangle2D.Double(18, 18, 764, 564);
ArrayList<MoveWave> waves = new ArrayList<>();
static String h1;
public void run() {
setTurnRadarRightRadians(Double.POSITIVE_INFINITY);
}
public void onScannedRobot(robocode.ScannedRobotEvent e) {
double bearing;
double distance;
double absoluteBearing;
Point2D.Double enemyPosition = project(myLocation = new Point2D.Double(getX(), getY()), absoluteBearing = (bearing = e.getBearingRadians()) + getHeadingRadians(), distance = e.getDistance());
double lateralVelocity = getVelocity() * Math.sin(bearing);
setTurnRightRadians(normalRelativeAngle(bearing + Math.PI / 2));
//bearing is bullet power
if ((bearing = (enemyEnergy - (enemyEnergy = e.getEnergy()))) <= 3 && bearing >= 0.09) {
MoveWave w;
(w = new MoveWave()).mea = Math.asin(8 / (w.speed = Rules.getBulletSpeed(bearing))) * oldLatVel >= 0 ? 1 : -1;
w.absBearing = absoluteBearing + Math.PI;
w.bins = statistics[(int) (Math.abs(oldLatVel)) >> 1];
w.source = (Point2D.Double) enemyPosition.clone();
waves.add(w);
addCustomEvent(w);
}
int dir;
if (!waves.isEmpty()) {
MoveWave surfWave;
double moveAngle;
double extra;
if (!battleField.contains(project((surfWave = waves.get(0)).source,
moveAngle = (absoluteBearing(surfWave.source, myLocation))
+ (extra = ((surfWave.source.distance(myLocation) / surfWave.speed - surfWave.time) * 8 / distance)), distance))) {
dir = 1;
} else {
int frontBin = surfWave.getBin(moveAngle);
if (!battleField.contains(project(surfWave.source, (moveAngle -= extra * 2), distance))) {
dir = -1;
} else {
dir = (surfWave.bins[frontBin] < surfWave.bins[surfWave.getBin(moveAngle)] ? -1 : 1);
}
}
setAhead(dir * 100);
}
setTurnRadarLeftRadians(getRadarTurnRemaining());
oldLatVel = lateralVelocity;
h1 += (char) ((int) Math.round(e.getVelocity() * Math.sin(absoluteBearing - e.getHeadingRadians())) + 8);
int b;
for (int matchLen = 30; matchLen >= 1; matchLen--) {
int size;
int matchi = h1.substring(0, (size = h1.length()) - (b = (int) (distance / 14))).lastIndexOf(h1.substring(size - matchLen, size));
if (matchi != -1) {
matchi += matchLen;
for (int i = 0; i < b; i++) {
absoluteBearing -= (h1.codePointAt(matchi + i) - 8) / distance;
}
setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));
setFire(2);
break;
}
}
}
static Point2D.Double project(Point2D.Double source, double angle, double distance) {
return new Point2D.Double(source.x + (distance * Math.sin(angle)), source.y + (distance * Math.cos(angle)));
}
public static double absoluteBearing(Point2D.Double p1, Point2D.Double p2) {
return Math.atan2(p2.x - p1.x, p2.y - p1.y);
}
public void onHitByBullet(robocode.HitByBulletEvent e) {
if (!waves.isEmpty()) {
MoveWave w;
double bin = (w = waves.get(0)).getBin(absoluteBearing(w.source, myLocation));
for (int i = 0; i < 31; i++) {
w.bins[i] += 1 / (Math.pow((i - bin) / 5, 2) + 1);
}
}
}
public class MoveWave extends Condition {
float[] bins;
double speed;
double mea;
int time;
double absBearing;
Point2D.Double source;
public int getBin(double angle) {
return (int) (normalRelativeAngle(angle - absBearing) / mea * 15 + 15.5);
}
@Override
public boolean test() {
if ((++time) * speed > source.distance(myLocation)) {
waves.remove(this);
}
return false;
}
}
}
To me it seems like you already shrinked the code quite well. There might be a few more tricks you could do, but I don't think you can get rid of over 100 bytes to make it micro. Maybe you can sacrifice some features, or take a look at some shrinking software, e.g. [1]
Thank you, It seems like it works but there is an error:
Could not find robocode/AdvancedRobot.class on Classpath Could not find robocode/Condition.class on Classpath
I understood the error but not sure about what to do.
First ideas:
You can use a simpler calculation for MEA.
Try compiling with JDK1.4, an old version of Robocode, and Jikes.
I've also used ProGuard to shrink Yatagan - it was a bit tricky to add the right stuff to the classpath and keep the right components 'open', but once it was set up it was easy.
With the MEA trick and some try catches I got it down to 769. I feel like a professional. =)
package dsekercioglu.micro;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import robocode.Condition;
import robocode.Rules;
import static robocode.util.Utils.normalRelativeAngle;
public class OculusMicro extends robocode.AdvancedRobot {
static float[][] statistics = new float[5][31];
static double enemyEnergy;
static double oldLatVel;
static Point2D.Double myLocation;
static Rectangle2D.Double battleField = new Rectangle2D.Double(18, 18, 764, 564);
ArrayList<MoveWave> waves = new ArrayList();
static String h1;
public void run() {
setTurnRadarRightRadians(Double.POSITIVE_INFINITY);
setAdjustRadarForGunTurn(true);
}
public void onScannedRobot(robocode.ScannedRobotEvent e) {
double distance;
double bearing;
double absoluteBearing;
Point2D.Double enemyPosition = project(myLocation = new Point2D.Double(getX(), getY()), absoluteBearing = (bearing = e.getBearingRadians()) + getHeadingRadians(), distance = e.getDistance());
setTurnRightRadians(normalRelativeAngle(bearing + Math.PI / 2));
MoveWave w;
if ((char) (((w = new MoveWave()).speed = (20 - 3 * (enemyEnergy - (enemyEnergy = e.getEnergy())))) - 11) <= 8) {
w.dir = (float) (Math.signum(oldLatVel + 0.001) * 1.15);
w.absBearing = absoluteBearing + Math.PI;
w.bins = statistics[(byte) (Math.abs(oldLatVel)) >> 1];
w.source = (Point2D.Double) enemyPosition.clone();
waves.add(w);
addCustomEvent(w);
}
oldLatVel = getVelocity() * Math.sin(bearing);
try {
MoveWave surfWave;
//bearing is move
bearing = (surfWave = waves.get(0)).timeForImpact * 8 / distance + Math.PI;
float lowestDanger = 1000;
for (int i = -1; i <= 1; i += 2) {
float danger;
double angle;
if ((danger = surfWave.bins[surfWave.getBin(angle = (absoluteBearing + bearing * i))]) < lowestDanger && battleField.contains(project(enemyPosition, angle, distance))) {
lowestDanger = danger;
setBack(i * 100);
}
}
} catch (Exception exc) {
}
setTurnRadarLeftRadians(getRadarTurnRemaining());
h1 += (char) (e.getVelocity() * Math.sin(absoluteBearing - e.getHeadingRadians()) + 8.5);
int matchLen = 30;
try {
while (matchLen-- > 0) {
int size;
int b;
int matchi = h1.substring(0, (size = h1.length()) - (b = (int) (distance / 14))).lastIndexOf(h1.substring(size - matchLen, size));
if (matchi != -1) {
matchi += matchLen;
for (int i = 0; i < b; i++) {
absoluteBearing -= (h1.codePointAt(matchi + i) - 8) / distance;
}
setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians()));
setFire(2);
break;
}
}
} catch (Exception exc) {
}
}
static Point2D.Double project(Point2D.Double source, double angle, double distance) {
return new Point2D.Double(source.x + (distance * Math.sin(angle)), source.y + (distance * Math.cos(angle)));
}
public void onHitByBullet(robocode.HitByBulletEvent e) {
try {
MoveWave w;
int bin = (w = waves.get(0)).getBin(Math.atan((myLocation.y - w.source.y) / (myLocation.x - w.source.x)));
int i = 0;
while (true) {
w.bins[i] += 1 / (Math.pow((i++) - bin, 2) + 1);
}
} catch (Exception exc) {
}
}
public class MoveWave extends Condition {
float[] bins;
double speed;
int time;
double absBearing;
int timeForImpact;
float dir;
Point2D.Double source;
public int getBin(double angle) {
return (int) (normalRelativeAngle(angle - absBearing) * speed * dir + 15.5);
}
@Override
public boolean test() {
if ((timeForImpact = (int) (source.distance(myLocation) - (++time) * speed)) < 0) {
waves.remove(this);
}
return false;
}
}
}