diff --git a/src/battle/BattleTest.java b/src/battle/BattleTest.java
index 26608c8ec4a7514d4e5e28848bd0e1cde5820e5a..4809ab471ade4b3942ccaa1a257569695efb9796 100644
--- a/src/battle/BattleTest.java
+++ b/src/battle/BattleTest.java
@@ -1,14 +1,8 @@
 package battle;
 
-import javax.swing.*;
-
-import asteroids.Action;
 import battle.controllers.EmptyController;
-import battle.controllers.FireController;
 import battle.controllers.FireForwardController;
-import battle.controllers.RotateAndShoot;
-import math.Vector2d;
-import utilities.JEasyFrame;
+import battle.controllers.webpigeon.StaticEvolver;
 
 /**
  * Created by simon lucas on 10/06/15.
diff --git a/src/battle/SimpleBattle.java b/src/battle/SimpleBattle.java
index 78e892680ed287f63db999ae026a75101fa0aa9b..4c4934bac62232c503232074f84417499d4b75a8 100644
--- a/src/battle/SimpleBattle.java
+++ b/src/battle/SimpleBattle.java
@@ -60,9 +60,6 @@ public class SimpleBattle {
         this.p2 = p2;
         reset();
 
-        stats.add(new PlayerStats(0, 0));
-        stats.add(new PlayerStats(0, 0));
-
         while (!isGameOver()) {
             update();
         }
@@ -70,12 +67,15 @@ public class SimpleBattle {
         return 0;
     }
 
-    protected void reset() {
+    public void reset() {
         stats.clear();
         objects.clear();
         s1 = buildShip(250, 250, 0);
         s2 = buildShip(300, 300, 1);
         this.currentTick = 0;
+
+        stats.add(new PlayerStats(0, 0));
+        stats.add(new PlayerStats(0, 0));
     }
 
     protected NeuroShip buildShip(int x, int y, int playerID) {
@@ -90,8 +90,8 @@ public class SimpleBattle {
         // get the actions from each player
 
         // apply them to each player's ship, taking actions as necessary
-        Action a1 = p1.getAction(this, 0);
-        Action a2 = p2.getAction(this, 1);
+        Action a1 = p1.getAction(this.clone(), 0);
+        Action a2 = p2.getAction(this.clone(), 1);
         update(a1, a2);
     }
 
diff --git a/src/battle/controllers/webpigeon/GaController.java b/src/battle/controllers/webpigeon/GaController.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6503d7751a2bb5cf1f4ad6b0610eed82b884095
--- /dev/null
+++ b/src/battle/controllers/webpigeon/GaController.java
@@ -0,0 +1,18 @@
+package battle.controllers.webpigeon;
+
+import asteroids.Action;
+
+/**
+ * Created by jwalto on 12/06/2015.
+ */
+public class GaController {
+    private double[] genome;
+
+    public GaController(double[] genome) {
+        this.genome = genome;
+    }
+
+    public Action getMove() {
+        return new Action(0,0, false);
+    }
+}
diff --git a/src/battle/controllers/webpigeon/GameEvaluator.java b/src/battle/controllers/webpigeon/GameEvaluator.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c5bff2acf432daf2ae80d94fe7dff8c7e2dba42
--- /dev/null
+++ b/src/battle/controllers/webpigeon/GameEvaluator.java
@@ -0,0 +1,39 @@
+package battle.controllers.webpigeon;
+
+import asteroids.Action;
+import battle.SimpleBattle;
+import ga.Eval2;
+
+/**
+ * Created by jwalto on 12/06/2015.
+ */
+public class GameEvaluator implements Eval2 {
+    private SimpleBattle battle;
+
+    public GameEvaluator(SimpleBattle battle, boolean reset) {
+        this.battle = battle.clone();
+
+        if (reset) {
+            this.battle.reset();
+        }
+    }
+
+    @Override
+    public double pointsDiff(double[] a, double[] b) {
+        SimpleBattle currBattle = battle.clone();
+        currBattle.reset();
+
+        GaController controller1 = new GaController(a);
+        GaController controller2 = new GaController(b);
+
+        while(!battle.isGameOver()) {
+            Action action1 = controller1.getMove();
+            Action action2 = controller2.getMove();
+
+            currBattle.update(action1, action2);
+        }
+
+        return 0;
+    }
+
+}
diff --git a/src/battle/controllers/webpigeon/StaticEvolver.java b/src/battle/controllers/webpigeon/StaticEvolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..e421b1b9c22e2a9a47970de2984ba7f363ea768b
--- /dev/null
+++ b/src/battle/controllers/webpigeon/StaticEvolver.java
@@ -0,0 +1,40 @@
+package battle.controllers.webpigeon;
+
+
+import asteroids.Action;
+import battle.DebugController;
+import battle.SimpleBattle;
+import battle.controllers.EmptyController;
+import ga.SimpleRandomHillClimberEngine;
+
+import java.awt.*;
+import java.util.Arrays;
+
+/**
+ * Created by jwalto on 12/06/2015.
+ */
+public class StaticEvolver {
+    private GameEvaluator eval;
+    private SimpleRandomHillClimberEngine rch;
+
+    public StaticEvolver(SimpleBattle battle) {
+        this.eval = new GameEvaluator(battle, true);
+        this.rch = new SimpleRandomHillClimberEngine(new double[]{0}, eval);
+    }
+
+    public double[] getBest() {
+        return rch.run(100);
+    }
+
+    public static void main(String[] args) {
+        SimpleBattle start = new SimpleBattle();
+        start.reset();
+
+        StaticEvolver evo = new StaticEvolver(start);
+        double[] best = evo.getBest();
+
+        System.out.println(Arrays.toString(best));
+    }
+
+
+}
diff --git a/src/ga/Eval2.java b/src/ga/Eval2.java
new file mode 100644
index 0000000000000000000000000000000000000000..70fd0b4ceecbe9cb390132f9c69a6d7d1b2ca16a
--- /dev/null
+++ b/src/ga/Eval2.java
@@ -0,0 +1,10 @@
+package ga;
+
+/**
+ * Created by jwalto on 12/06/2015.
+ */
+public interface Eval2 {
+
+    double pointsDiff(double[] a, double[] b);
+
+}
diff --git a/src/ga/SimpleRandomHillClimber.java b/src/ga/SimpleRandomHillClimber.java
index 70a3d335441723e307106d141dfcab70e6553e14..fa1fe3dcad764b40516c9d53ce244bfb7fa13981 100644
--- a/src/ga/SimpleRandomHillClimber.java
+++ b/src/ga/SimpleRandomHillClimber.java
@@ -1,4 +1,4 @@
-package ea;
+package ga;
 
 import java.util.Arrays;
 import java.util.Random;
diff --git a/src/ga/SimpleRandomHillClimberEngine.java b/src/ga/SimpleRandomHillClimberEngine.java
new file mode 100644
index 0000000000000000000000000000000000000000..e320fcdc50a47fc3c2f75ac046a676b9479d41d7
--- /dev/null
+++ b/src/ga/SimpleRandomHillClimberEngine.java
@@ -0,0 +1,101 @@
+package ga;
+
+import java.util.Arrays;
+import java.util.Random;
+
+public class SimpleRandomHillClimberEngine {
+
+    // Random mutation hill climber
+    // using a relative (hence co-evolutionary)
+    // fitness function
+    static Random random = new Random();
+
+    double[] bestYet;
+    Eval2 eval;
+
+    double stepFac = 0.1;
+
+    // set stepAdjust to 1.0 to keep the stepFac fixed
+
+    // on quadratic bowl 1.01 works much better than 1.0
+    // which increases the step size every time a mutation
+    // is successful and decreases it every time it fails
+    // to improve
+    // but be careful: could it make things worse in some cases?
+    double stepAdjust = 1.01;
+
+    // example ready for a minimal version of
+    // co-evolution
+
+    public static void main(String[] args) {
+        int nEvals = 1000;
+        int nDim = 10;
+        double[] init = randVec(nDim);
+        SimpleRandomHillClimberEngine evo = new SimpleRandomHillClimberEngine(init, new QuadraticBowl());
+
+        evo.run(nEvals);
+
+        System.out.println("Best Found: " + Arrays.toString(evo.bestYet));
+        System.out.println("Fitness: " + mag2(evo.bestYet));
+
+    }
+
+    public SimpleRandomHillClimberEngine(double[] bestYet, Eval2 eval) {
+        this.bestYet = bestYet;
+        this.eval = eval;
+    }
+
+    public double[] run(int nEvals) {
+        for (int i=0; i<nEvals; i++) {
+            // randomly mutate the best yet
+            double[] mut = randMut(bestYet, stepFac);
+            double diff = eval.pointsDiff(bestYet, mut);
+
+            // if it's better then adopt the mutation as the new best
+            if (diff >= 0) {
+                bestYet = mut;
+                // try making it bigger - make even faster progress
+            } else {
+                // try making the step size smaller
+                stepFac /= stepAdjust;
+            }
+            System.out.println(i + "\t " + mag2(bestYet));
+        }
+
+        return bestYet;
+    }
+
+    static double[] randVec(int n) {
+        double[] x = new double[n];
+        for (int i=0; i<n; i++) {
+            x[i] = random.nextGaussian();
+        }
+        return x;
+    }
+
+    static double[] randMut(double[] v, double stepFac) {
+        int n = v.length;
+        double[] x = new double[n];
+        for (int i=0; i<n; i++) {
+            x[i] = v[i] + stepFac * random.nextGaussian();
+        }
+        return x;
+    }
+
+    static class QuadraticBowl implements Eval2 {
+
+        @Override
+        public double pointsDiff(double[] a, double[] b) {
+            // simple example that evaluates quality as being
+            // the minimum squared magnitude of a vector
+            return mag2(a) - mag2(b);
+        }
+    }
+
+    static double mag2(double[] v) {
+        // square of the magnitude of the vector
+        double tot = 0;
+        for (double x : v) tot += x * x;
+        return tot;
+    }
+}