Help talk:Code Shrinking

From Robowiki
Jump to navigation Jump to search

Contents

Thread titleRepliesLast modified
Shrinking OculusMicro712:50, 16 December 2017
Shrinking Hammer418:51, 14 February 2017

Shrinking OculusMicro

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;
        }
    }
}
Dsekercioglu (talk)20:24, 10 December 2017

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]

Cb (talk)17:43, 11 December 2017

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.

Dsekercioglu (talk)11:06, 12 December 2017

I am not sure either, I never saw this error before.

If it won't work, you could also try using other shrinking software, there are a lot of tools available.

Cb (talk)12:42, 12 December 2017
 
 

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.

Skilgannon (talk)22:59, 12 December 2017
(edit: more details) With the MEA trick and some try catches I got it down to 769. I also wrote the surfing algorithm with a for loop. Removed absoIuteBearing method since it was used only once. 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;
        }
    }
}
Dsekercioglu (talk)07:58, 15 December 2017

That while (true) loop looks scary :P Pretty cool if it's working though. I am excited to hopefully see OculusMicro in the rumble soon :D

Cb (talk)12:18, 16 December 2017
 

Have a look at RaikoMicro, which is full of tricks.

e.g., for waves, no ArrayList, use addCustomEvents instead.

Xor (talk)12:50, 16 December 2017
 
 
 

Shrinking Hammer

Anyone with an idea?

Dsekercioglu (talk)00:02, 12 February 2017

Doesn't look like it could be shrunk much more from here without sacrificing features . . Not sure. There's some software on the internet though which might help.

Natesurf (talk)20:34, 12 February 2017
 

Got it down to 259. Just use robocode.util.Utils.normalRelativeAngle( (code here) ) instead of importing files, and don't initialize i1 to 0 (The default value is already 0!)

Natesurf (talk)20:43, 12 February 2017

I shrunk it to 253. Now I am using the thing you said about normalReativeAngle

It is 253 again =(


package dsekercioglu;

import robocode.*;

public class Hammer extends AdvancedRobot {

   public static int[] m = new int[10];
   public static int i1;
   public static String h = "��������������������������������������������������������������������������������������������";
   public void run() {
       setTurnRadarRightRadians(Double.POSITIVE_INFINITY);
   }
   public void onScannedRobot(ScannedRobotEvent e) {
       double be;
       setTurnRightRadians((be = e.getBearingRadians()) + 1.5707963267948966D);
       setAhead((m[(i1 / 15)] % 3 - 1) * 36);
       i1 = (i1 + 1) % 150;
       be += getHeadingRadians();
       int a = (int) Math.round(e.getVelocity() * Math.sin(be - e.getHeadingRadians())) + 8;
       h += (char) a;
       double d;
       int b = (int) ((d = e.getDistance()) / 14);
       int matchi = h.substring(0, h.length() - b).lastIndexOf(a);
       for (int i = 1; i < b; i++) {
           be -= (h.codePointAt(matchi + i) - 8) / d;
       }
       setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(be - getGunHeadingRadians()));
       setFire(2);
       setTurnRadarLeftRadians(getRadarTurnRemaining());
   }
   public void onHitByBullet(HitByBulletEvent e) {
       m[(i1 / 15)] += 1;
   }
   public void onHitWall(HitWallEvent e) {
       onHitByBullet(null);
   }

}

Dsekercioglu (talk)18:49, 14 February 2017
 

I have a question. I used byte instead of int(without any extra casting) it increased the code size 1 byte.

Dsekercioglu (talk)18:51, 14 February 2017