/* @(#)MovePopulation.java
 */
/**
 *
 *
 * @author <a href="mailto:geoff@minty-dark-tower">Geoff Shannon</a>
 */
package wall_follower;

import java.util.Random;
import java.util.NavigableSet;
import java.util.TreeSet;


public class MovePopulation {
    TreeSet<Move> nonePressed;
    TreeSet<Move> leftPressed;
    TreeSet<Move> rightPressed;
    TreeSet<Move> leftAndRight;
    Random rand;

    public MovePopulation(Random rand) {
        this.rand = rand;
        this.nonePressed = new TreeSet<Move>();
        this.leftPressed = new TreeSet<Move>();
        this.rightPressed = new TreeSet<Move>();
        this.leftAndRight = new TreeSet<Move>();
    }

    public void add(Move move) {
        NavigableSet<Move> set = getSetForMove(move);
        set.add(move);
    }

    public Move getMoveForReading(SensorReading reading) {
        Move move = new Move(reading);
        Move minMove = new Move(reading);
        minMove.minDistance = reading.distance - Move.DISTANCE_RANGE;

        NavigableSet<Move> set = getSetForMove(move);

        NavigableSet<Move> legalMoves = set.subSet(minMove, true,
                                             move, true);

        if (legalMoves.size() == 0) {
            seedPopulationForReading(reading);
            return getMoveForReading(reading);
        }

        Move finalMove = legalMoves.first();
        int size = legalMoves.size();
        int item = rand.nextInt(size);
        int i = 0;
        for (Move m : legalMoves) {
            if (i == item) {
                finalMove = m;
            }
            i++;
        }
        return finalMove;
    }

    private NavigableSet<Move> getSetForMove(Move move) {
        if (move.leftPressed && move.rightPressed) {
            return leftAndRight;
        } else if (move.leftPressed) {
            return leftPressed;
        } else if (move.rightPressed) {
            return rightPressed;
        } else {
            return nonePressed;
        }
    }

    /**
     *  This method MUST ensure that getMoveForReading will find at
     *  least one legal move.  It is used to generate populations on
     *  the fly for new situations.
     */
    public void seedPopulationForReading(SensorReading reading) {
        NavigableSet<Move> set = getSetForMove(new Move(reading));
        for (int i = 0; i < 10; i++) {
            set.add(new Move(reading, rand));
        }
    }
}

@@ -1615,24 +1615,170 @@
 ove;%0A    %7D%0A%0A
+    private NavigableSet%3CMove%3E getSetForReading(SensorReading reading) %7B%0A        return getSet(reading.leftPressed, reading.rightPressed);%0A    %7D%0A%0A
     private 
@@ -1831,19 +1831,29 @@
         
-if 
+return getSet
 (move.le
@@ -1865,11 +1865,9 @@
 ssed
- &&
+,
  mov
@@ -1873,37 +1873,139 @@
 ve.rightPressed)
+;%0A    %7D%0A%0A    private NavigableSet%3CMove%3E getSet(boolean left, boolean right) %7B%0A        if (left && right)
  %7B%0A
-  
           return
@@ -2038,32 +2038,20 @@
 lse if (
-move.leftPressed
+left
 ) %7B%0A    
@@ -2097,33 +2097,21 @@
 lse if (
-move.rightPressed
+right
 ) %7B%0A    
@@ -2506,21 +2506,15 @@
 tFor
-Move(new Move
+Reading
 (rea
@@ -2518,17 +2518,16 @@
 reading)
-)
 ;%0A      

Arrange interface of private getSet method better