Using the Simulator in Chapter 3 and Later

Starting in Chapter 3, students write their own classes and methods. Here is how to make this work. The example here is the StairSweeper class of Chapter 3.

There are now three parts. You need to write a class with your new robot type, you need to create a compatible extension to KarelWorld that defines the setup and the task, and you need to edit KarelProgram. Here are the details.

First, here is the StairSweeer.java file. Note that in general it is very easy to import existing Karel code from earlier simulators. the imports will be a bit different, and the Directions are in class Direction: Direction.NORTH, etc.

package alice.kareluser;

import org.alice.apis.moveandturn.Color;

import alice.kareltherobot.Direction;
import alice.kareltherobot.UrRobot;

/**
 * The task of a stair sweeper is to climb three steps and pick up a beeper from each
 * step.
 * 
 * @author jbergin
 * 
 */
public class StairSweeper extends UrRobot
{

	/**
	 * Create a robot on a specific street and avenue, facing a given direction with no
	 * beepers.
	 * 
	 * @param street the street on which to place the robot
	 * @param avenue the avenue on which to place the robot
	 * @param direction the direction the robot will initially face
	 */
	public StairSweeper(int street, int avenue, Direction direction)
	{
		super(street, avenue, direction);

	}

	/**
	 * Create a robot on a specific street and avenue, facing a given direction with a
	 * given number of beepers.
	 * 
	 * @param street the street on which to place the robot
	 * @param avenue the avenue on which to place the robot
	 * @param direction the direction the robot will initially face
	 * @param beepers the initial number of beepers in the beeper bag
	 */
	public StairSweeper(int street, int avenue, Direction direction, int beepers)
	{
		super(street, avenue, direction, beepers);

	}

	/**
	 * Create a robot on a specific street and avenue, facing a given direction with a
	 * given number of beepers and a given body color.
	 * 
	 * @param street the street on which to place the robot
	 * @param avenue the avenue on which to place the robot
	 * @param direction the direction the robot will initially face
	 * @param beepers the initial number of beepers in the beeper bag
	 * @param color the color of this robot
	 */
	public StairSweeper(int street, int avenue, Direction direction, int beepers,
			Color color)
	{
		super(street, avenue, direction, beepers, color);
	}

	/**
	 * Robot turns 90 degrees clockwise (to its right).
	 */
	public void turnRight()
	{
		turnLeft();
		turnLeft();
		turnLeft();
	}

	/**
	 * Climb a stair one "street" high and one "avenue" wide.
	 */
	public void climbStair()
	{
		turnLeft();
		move();
		turnRight();
		move();
	}


	/**
	 * Perform the task and announce its completion.
	 */
	public void task()
	{
		climbStair();
		pickBeeper();
		think("Found a beeper here.", 2);
		climbStair();
		pickBeeper();
		think("Found a second beeper here.", 2);
		climbStair();
		pickBeeper();
		think("Found a third beeper here.", 2);
		turnOff();
	}

}

Here the task of  the robot is in the task method.

You also need a world class. Here we call it StairSweeperWorld. As always, it has the setTheStage and run methods. Since there is only one robot in this scenario, we can just send that robot the task message in the run here. With several robots you may want to expand the common task in this run method, especially if the robots come from different classes.

package alice.kareluser;

import org.alice.apis.moveandturn.AbstractCamera;

import alice.kareltherobot.Direction;
import alice.kareltherobot.KarelWorld;

/**
 * A simple world in which a stair sweeper will pick a beeper from each (of three)
 * steps.
 * 
 * @author jbergin
 * 
 */
public class StairSweeperWorld extends KarelWorld
{

	private StairSweeper karel;

	/**
	 * Execute the stair sweeping task
	 * 
	 */
	@Override
	public void run()
	{
		karel.task();
	}

	/**
	 * Set up the stair sweeping situation. 
	 * 
	 */
	@Override
	public void setTheStage()
	{
		addDecorations();
		
		karel = new StairSweeper(1, 1, Direction.EAST, 0);
		karel.setTracing(true);
		AbstractCamera camera = getCamera();
		addRobot(karel);
		camera.pointAt(karel);
		cameraFollow(camera, karel);
		readWorld("worlds", "fig3-1.kwld");
	}

}

The final part is the modification to KarelProgram, which just creates this world instead of some other (along with the other canonical messages that are already there.) This is exactly the same as the Chapter 2 example except for the one line that creates the world object.

package alice.kareluser;

import org.alice.apis.moveandturn.Program;


import alice.kareltherobot.KarelWorld;


/**
 * A framework in which to initialize a robot task. You can copy this file for your own
 * work, or simply edit it.
 * 
 * @author Cay Horstmann (with edits by Joe Bergin)
 * 
 */
public class KarelProgram extends Program
{
	
	private static final long serialVersionUID = 1L;
	private KarelWorld scene;

	/**
	 * Create a world of interest. Edit this for your own worlds. This is the only method
	 * you should need to edit. Create the world object and assign it to the scene variable.
	 * Make sure you send it the setTheStage message. 
	 */
	public KarelProgram()
	{
		// Create an object here from a class that extends KarelWorld.

		scene = new StairSweeperWorld();

		// leave the next statement here. It sets up your world. 
		scene.setTheStage();
	}

	/**
	 * Tell the program which scene to "run"
	 * 
	 * @see edu.cmu.cs.dennisc.program.Program#initialize()
	 */
	@Override
	protected void initialize()
	{
		setScene(scene);
	}
	
	
	/**
	 * Execute the simulation defined in the scene
	 * 
	 * @see edu.cmu.cs.dennisc.program.Program#run()
	 */
	@Override
	protected void run()
	{
		scene.run();
	}

	public static void main(String[] args)
	{
		KarelProgram theProgram = new KarelProgram();
		theProgram.showInJFrame(args, true);

	}
}

Now run KarelProgram as your main as usual.

Last Updated: March 16, 2010