package spacefront;

import java.util.Observable;

public class Research extends Observable {

    public static final int OFFENSE = 0;
    public static final int DEFENSE = 1;

    private static final double RATE = 0.001;
    private static final double CURVE = 2;

    private double[] research = new double[2];
    private double defense;
    private int focus = OFFENSE;

    public void setFocus(int target) {
        focus = check(target);
    }

    public void step() {
        int orig = getLevel(focus);
        research[focus] += RATE;
        if (getLevel(focus) > orig) {
            setChanged();
            notifyObservers();
        }
    }

    private double getRawLevel(int target) {
        return Math.pow(research[check(target)], 1d / CURVE);
    }

    public int getLevel(int target) {
        return (int) getRawLevel(target);
    }

    public double getProgress(int target) {
        int base = getLevel(target);
        double low = Math.pow(base, CURVE);
        double current = research[target];
        double high = Math.pow(base + 1, CURVE);
        return (current - low) / (high - low);
    }

    private int check(int target) {
        if (target < 0 || target > 1) {
            throw new IllegalArgumentException("Bad focus: " + target);
        }
        return target;
    }
}

@@ -171,16 +171,53 @@
 E = 1;%0A%0A
+    public static final int MAX = 9;%0A
     priv
@@ -254,16 +254,16 @@
  0.001;%0A
-
     priv
@@ -578,16 +578,137 @@
 = RATE;%0A
+        if (Math.pow(research%5Bfocus%5D, 1d / CURVE) %3E MAX) %7B%0A            research%5Bfocus%5D = Math.pow(MAX, CURVE);%0A        %7D%0A
         
@@ -791,16 +791,42 @@
 servers(
+new Event(focus, orig + 1)
 );%0A     
@@ -1459,32 +1459,32 @@
 get);%0A        %7D%0A
-
         return t
@@ -1495,11 +1495,655 @@
 t;%0A    %7D
+%0A%0A    public static class Event %7B%0A%0A        private final int focus;%0A        private final int level;%0A%0A        public Event(int focus, int level) %7B%0A            this.focus = focus;%0A            this.level = level;%0A        %7D%0A%0A        public int getFocus() %7B%0A            return focus;%0A        %7D%0A%0A        public int getLevel() %7B%0A            return level;%0A        %7D%0A%0A        @Override%0A        public String toString() %7B%0A            String name;%0A            if (focus == OFFENSE) %7B%0A                name = %22OFFENCE%22;%0A            %7D else %7B%0A                name = %22DEFENSE%22;%0A            %7D%0A            return %22%5B%22 + name + %22: %22 + level + %22%5D%22;%0A        %7D%0A    %7D
 %0A%7D%0A

Enhance Research a bit.