KarelFixture.
TestHighJumpStrategy
On this page we will demonstrate a simple but explicit strategy. A robot will use a high jump strategy to jump and fetch a basketball (beeper).


kareltherobot.KarelFixture
kareltherobot.HighJumper
Create karel 1 2 North 0
Class kareltherobot.ThreeJump
Create three
Class kareltherobot.FiveJump
Create five
World reset
World placeBeepers 4 2 2
World placeBeepers 6 2 1
Message karel setStrategy three
Message karel fetch
Message karel fetch
Assert BeepersAt 4 2 0
Assert BeepersAt 1 2 2
Assert At karel 1 2
Assert FacingNorth karel
Message karel setStrategy five
Message karel fetch
Assert BeepersAt 6 2 0
Assert BeepersAt 1 2 3
Assert At karel 1 2
Assert FacingNorth karel
Assert Running karel

Here is the code for this. A Jump Strategy is defined by an interface that also defines a "nojumping" implementation. (Using an anonymous inner class). It is worth noting that these classes were created specifically for this page and that as I write this they have been executed no other way than here. This is both a tester and an executor of code. And yes, I did find some bugs in developing this. Forgetting to have the robot turn around at the end of a fetch, for example.
public interface JumpStrategy
{
    public void jump(UrRobot who);
    
    public static final JumpStrategy SimplePick = new JumpStrategy()
    {
      public void jump(UrRobot who)
      {
          who.pickBeeper();
      }
    };
}


A Three Jump looks like the following. A Five Jump is similar.
public class ThreeJump implements JumpStrategy
{

    public void jump(UrRobot who)
    {
        who.move();
        who.move();
        who.move();
        who.pickBeeper();
        who.turnLeft();
        who.turnLeft();
        who.move();
        who.move();
        who.move();
        who.putBeeper();
        who.turnLeft();
        who.turnLeft();
    }

}


Finally, the robot that knows how to use these is like this:
public class HighJumper extends UrRobot
{

    public HighJumper(int street, int avenue, Direction direction, int beepers, Color badge)
    {
        super(street, avenue, direction, beepers, badge);
    }

    public HighJumper(int street, int avenue, Direction direction, int beepers)
    {
        super(street, avenue, direction, beepers);
    }
    
    public void setStrategy(JumpStrategy strategy)
    {
        this.strategy = strategy;
    }
    
    public void fetch()
    {
        strategy.jump(this);
    }
    
    private JumpStrategy strategy = JumpStrategy.SimplePick;
}


Note that there is nothing special about Jumping in a jump strategy except the name. This is really just a general one method strategy.


Exercise

Modify this so that a strategy has a way to "remember" how many moves (use a new method instead of move) it makes going up so that it can automatically turn around, move the same number, and then turn around again. The body of a strategy would then look something like:
public class FourJump implements JumpStrategy
{

    public void jump(UrRobot who)
    {
        moveRemember(who);
        moveRemember(who);
        moveRemember(who);
        moveRemember(who);
        who.pickBeeper();
        returnToBaseline(who);
        who.putBeeper();
    }

     private void moveRemember(UrRobot who)
     {	
         who.move();
   	 memory.remember();
     }

. . . memory . . .
}


A jump strategy could use its own strategy, of course, to remember. Hint: Think decorators.

[ User Guide] [.FrontPage] [.RecentChanges]