The chapters and problems are from Karel the Robot Learns Java written by Eric Roberts for Stanford's CS106A and CS106A's assignments. My edits are colored green. The editor is powered by Esprima. My JavaScript inheritance pattern is inspired by Douglas Crockford, John Resig, Mozilla, and oopsjs.

This page is under heavy construction. There are many more chapters and problems to translate. I would really appreciate your help and/or feedback! You can find my contact info here.

In the 1970s, a Stanford graduate student named Rich Pattis decided that it would be easier to teach the fundamentals of programming if students could somehow learn the basic ideas in a simple environment free from the complexities that characterize most programming languages. Drawing inspiration from the success of Seymour Papert’s LOGO project at MIT, Rich designed an introductory programming environment in which students teach a robot to solve simple problems. That robot was named Karel, after the Czech playwright Karel Capek, whose 1923 play R.U.R. (Rossum’ s Universal Robots) gave the word robot to the English language.

Karel the Robot was quite a success. Karel was used in introductory computer science courses all across the country, to the point that Rich’s textbook sold well over 100,000 copies. Many generations of CS106A students learned how programming works by putting Karel through its paces. But nothing lasts forever. In the middle of the 1990s, the simulator we had been using for Karel the Robot stopped working. We were, however, soon able to get a version of Karel up and running in the Thetis interpreter we were using at the time. But then, a year ago (2004), CS106A switched to Java, and Karel again vanished from the scene. For the last three quarters, the hole in the curriculum left by Karel’s departure has been competently filled by Nick Parlante’s Binky world, but it seems about time to bring Karel back. JavaScript is the language of the web. And though it is so popular, most people dismiss it as a weak scripting language, and few people know it intimately. Hopefully this will get people thinking more about this powerful object-oriented, functional programming language.

What is Karel?

Karel is a very simple robot living in a very simple world. By giving Karel a set of commands, you can direct it to perform certain tasks within its world. The process of specifying those commands is called programming. Initially, Karel understands only a very small number of predefined commands, but an important part of the programming process is teaching Karel new commands that extend its capabilities.

When you program Karel to perform a task, you must write out the necessary commands in a very precise way so that the robot can correctly interpret what you have told it to do. In particular, the programs you write must obey a set of syntactic rules that define what commands and language forms are legal. Taken together, the predefined commands and syntactic rules define the Karel programming language. The Karel programming language is designed to be as similar as possible to JavaScript so as to ease the transition to the language of the web. Karel programs have much the same structure and involve the same fundamental elements as Javasciprt programs do. The critical difference is that Karel’s programming language is extremely small, in the sense that it has very few commands and rules. It is easy, for example, to teach the entire Karel language in just a couple of hours, which is precisely what we do in CS106A. At the end of that time, you will know everything that Karel can do and how to specify those actions in a program. The details are easy to master. Even so, you will discover that solving a problem can be extremely challenging. Problem solving is the essence of programming; the rules are just a minor concern along the way.

In sophisticated languages like JavaScript, there are so many details that learning these details often becomes the focus of the course. When that happens, the much more critical issues of problem solving tend to get lost in the shuffle. By starting with Karel, you can concentrate on solving problems from the very beginning. And because Karel encourages imagination and creativity, you can have quite a lot of fun along the way.

Karel’s world

Karel’s world is defined by streets running horizontally (east-west) and avenues running vertically (north-south). The intersection of a street and an avenue is called a corner. Karel can only be positioned on corners and must be facing one of the four standard compass directions (north, south, east, west). A sample Karel world is shown below. Here Karel is located at the corner of 1st Street and 1st Avenue, facing east.

Several other components of Karel’s world can be seen in this example. The object in front of Karel is a beeper. As described in Rich Pattis’s book, beepers are “plastic cones which emit a quiet beeping noise.” Karel can only detect a beeper if it is on the same corner. The solid lines in the diagram are walls. Walls serve as barriers within Karel’s world. Karel cannot walk through walls and must instead go around them. Karel’s world is always bounded by walls along the edges, but the world may have different dimensions depending on the specific problem Karel needs to solve.

What can Karel do?

When Karel is shipped from the factory, it responds to a very small set of commands:

move() Asks Karel to move forward one block. Karel cannot respond to a move() command if there is a wall blocking its way.
turnLeft() Asks Karel to rotate 90 degrees to the left (counterclockwise).
pickBeeper() Asks Karel to pick up one beeper from a corner and stores the beeper in its beeper bag, which can hold an infinite number of beepers. Karel cannot respond to a pickBeeper() command unless there is a beeper on the current corner.
putBeeper() Asks Karel to take a beeper from its beeper bag and put it down on the current corner. Karel cannot respond to a putBeeper() command unless there are beepers in its beeper bag.

The empty pair of parentheses that appears in each of these commands is part of the common syntax shared by Karel and JavaScript and is used to specify the invocation of the command. Eventually, the programs you write will include additional information in the space between the parentheses, but such information is not part of the Karel’s primitive world. These parentheses will therefore be empty in standard Karel programs, but you must remember to include them nonetheless.

It is also important to recognize that several of these commands place restrictions on Karel’s activities. If Karel tries to do something illegal, such as moving through a wall or picking up a nonexistent beeper, an error condition occurs. At this point, Karel displays an error message and does not execute any remaining commands.

Karel’s commands, however, cannot be executed on their own. Before Karel can respond to any of these commands, you need to incorporate them into a Karel program. You will have a chance to see a few simple Karel programs in Chapter 2, but before doing so, it is useful to make a few general remarks about the programming philosophy that underlies this particular implementation of the Karel programming language.

Karel and the object-oriented paradigm

When Karel was introduced in the 1970s, the prevailing approach to writing computer programs was the procedural paradigm. To a large extent, procedural programming is the process of decomposing a large programming problem into smaller, more manageable units called procedures that define the necessary operations. Although the strategy of breaking programs down into smaller units remains a vital part of any style of programming, modern languages like Java emphasize a different approach called the object-oriented paradigm. In object-oriented programming, the programmer’s attention shifts away from the procedural specification of operations and focuses instead on modeling the behavior of conceptually integrated units called objects. Objects in a programming language sometimes correspond to physical objects in the real world, but just as often represent more abstract concepts. The central feature of any object—real or abstract—is that it must make sense as a unified whole.

One of the primary advantages of the object-oriented paradigm is that it encourages programmers to recognize the fundamental relationship between the state of an object and its behavior. The state of an object consists of a set of attributes that pertain to that object and might change over time. For example, an object might be characterized by its location in space, its color, its name, and a host of other properties. The behavior of an object refers to the ways in which that object responds to events in its world or commands from other objects. In the language of object-oriented programming, the generic word for anything that triggers a particular behavior in an object is called a message (although it generally seems clearer to use the word command in the context of Karel). The response to a message typically involves changing the state of an object. For example, if one of the properties defining the state of an object is its color, then it would presumably respond to a setColor(BLUE) message by changing its color to blue.

In many ways, Karel represents an ideal environment for illustrating the object- oriented approach. Although no one has actually built a mechanical implementation of Karel, it is nonetheless easy to imagine Karel as a real-world object. Karel is, after all, a robot, and robots are real-world entities. The properties that define Karel’s state are its location in the world, the direction it is facing, and the number of beepers in its beeper bag. Karel’s behavior is defined by the commands to which it responds: move(), turnLeft(), pickBeeper(), and putBeeper(). The move() command changes Karel’s location, turnLeft() changes its direction, and the remaining two affect both the number of beepers in Karel’s bag and the number of beepers on the current corner.

The Karel environment also provides a useful framework for defining one of the central concepts of object-oriented programming. In both Karel and Java, it is essential to differentiate the notion of an object from that of a class. The easiest way to understand the distinction is to think about a class as a pattern or template for objects that share a common behavior and collection of state attributes. As you will see in the next chapter, the word Karel in a Karel program represents the entire class of robots that know how to respond to the move(), turnLeft(), pickBeeper(), and putBeeper() commands. Whenever you have an actual robot in the world, that robot is an object that represents a specific instance of the Karel class. Although you won’t have occasion to do so here, it is possible to have more than one instance of the Karel class running in the same world. Even when there is only a single robot, however, it is important to remember that object and class are different concepts and to keep those ideas straight in your mind.

The importance of practical experience

Programming is very much a learn-by-doing activity. As you will continually discover in your study of computer science, reading about some programming concept is not the same thing as using that concept in a program. Things that seem very clear on the page can be difficult to put into practice.

Because this site is written entirely in JavaScript, it should work the same across operating systems and does not require any configuration on your part. Even though the programming environment you use has a great deal of influence on the nitty-gritty details you need to run programs, it has no influence whatsoever on the general concepts. This book describes the general concepts; the details pertinent to each platform will be distributed as handouts during the course.

The fact that this book omits the practical details, however, should in no sense be interpreted as minimizing their importance. If you want to understand how programming works—even in an environment as simple as that provided by Karel—it is essential to “get your hands dirty” and start using the computer. Doing so is by far the most effective introduction into the world of programming and the excitement that it holds.

In its new object-oriented implementation, the simplest style of Karel program consists of a definition of a new Karel class that specifies a sequence of built-in commands that should be executed when the program is run. A very simple Karel program is shown in the editor.

The program in the editor is composed of several parts. The first part consists of the following lines:

/*
 * File: BeeperPickingKarel.js
 * -----------------------------
 * The BeeperPickingKarel class extends the basic Karel class
 * by defining a "run" method with three commands.  These
 * commands cause Karel to move forward one block, pick up
 * a beeper, and then move ahead to the next corner.
 */

These lines are an example of a comment, which is simply text designed to explain the operation of the program to human readers. Comments in Karel, Java, and JavaScript begin with the characters /* and end with the characters */. Here, the comment begins on the first line and ends several lines later. The stars on the individual lines that make up the text of the comment are not required, but make it easier for human readers to see the extent of the comment. In a simple program, extensive comments may seem silly because the effect of the program is obvious, but they are extremely important as a means of documenting the design of larger, more complex programs.

The second part of the program is the class definition

function BeeperPickingKarel(world) {
    this.inheritFrom(new Karel(world));
    var self = this;

    this.run = function() {
        self.move();
        self.pickBeeper();
        self.move();
    }
}

To understand this definition, it is useful to look more carefully at its structure. The definition of the BeeperPickingKarel class consists of the line beginning with function BeeperPickingKarel and encompasses everything between the curly brace at the end of that line and the corresponding closing brace on the last line of the program. The single line that introduces the new class is called the signature which defines the constructor, new BeeperPickingKarel(world); the code between the braces is called the body.

In programming, it is often very useful to think about a particular definition and its body as separable ideas. In this example, the definition of BeeperPickingKarel has the following form, where the entire body of the definition has been replaced by a box that you can put out of your mind for the moment:

function BeeperPickingKarel(world) {
    this.extends_(new Karel(world));
    var self = this;

    +------------------+
    | class definition |
    +------------------+
}

The class definition is explained in the editor with more comments. Comments can also begin with //.

In object-oriented languages, defining a new class by extension means that the new class (here, BeeperPickingKarel) builds on the facilities provided by the existing class (in this case, Karel). In particular, the fact that it extends Karel guarantees that the new BeeperPickingKarel class will have the following properties :

  1. Any instance of the class BeeperPickingKarel is also an instance of the class Karel. Any instance of the class Karel represents a robot that lives in a world of streets, avenues, beepers, and walls whose state consists of its location, direction, and the number of beepers in its bag. Because BeeperPickingKarel is an extension of Karel, you know that an instance of BeeperPickingKarel will also be a robot that lives in the same type of world and has the same state properties.
  2. Any instance of the BeeperPickingKarel class will automatically respond to the same commands as an instance of the Karel class. Because every robot in the Karel class knows how to respond to the commands move(), turnLeft(), pickBeeper(), and putBeeper(), it follows that a instance of BeeperPickingKarel will understand that same set of commands.

In other words, the new BeeperPickingKarel class automatically acquires the state attributes and the behavior of the Karel class from which it is derived. The process of taking on the structure and behavior of the parent class is called inheritance.

When a class is defined by extension, the new class is said to be a subclass of the original. In this example, BeeperPickingKarel is therefore a subclass of Karel. Symmetrically, Karel is said to be a superclass of BeeperPickingKarel. Unfortunately, this terminology can be confusing for new programmers, who are likely to make the intuitive inference that a subclass is somehow less powerful that its superclass when in fact the opposite is true. A subclass inherits the behavior of its superclass and can therefore respond to the entire set of commands available to that superclass. A subclass, however, usually defines additional commands that are unavailable to the superclass. Thus, the typical subclass actually has more functionality than the class from which it was derived. This idea is expressed much more clearly by the notion of extension: a subclass extends its superclass and can therefore add new capabilities to it.

Now that you have some idea about what class extension means, it now makes sense to look at the body of the BeeperPickingKarel class. That body consists of the following lines:

this.run = function() {
    self.move();
    self.pickBeeper();
    self.move();
}

These lines represent the definition of a new method, which specifies the sequence of steps necessary to respond to a command. As in the case of the BeeperPickingKarel class itself, the method definition consists of two parts that can be considered separately: The first line constitutes the method header and the code between the curly braces is the method body. If you ignore the body for now, the method definition looks like this:

this.run = function() {
    +-------------------------------+
    | body of the method definition | 
    +-------------------------------+
}

The this.<name> pattern is for public methods which we will cover later. <name> specifies the name of the new method, which in this case is the method run. Defining a method means that the new Karel subclass can respond to a new command with that name. The built-in Karel class responds to the commands move(), turnLeft(), pickBeeper(), and putBeeper(); a BeeperPickingKarel responds to that same set of commands plus a new command called run. The run command is called at the end of the program. To run the program, click the "Run" button. The effect of issuing that command is defined by the body of the run method, which is a sequence of commands that the robot will execute in order. For example, the body of the run method for the BeeperPickingKarel class is

move();
pickBeeper();
move();

In every exercise, Karel's world will show Karel's start position, finish position, and may have initial and final beeper locations. In the world below, Karel's start position is in the bottom-left at the corner of 1st Avenue and 1st Street (1, 1). Karel's finish position is at 3rd Avenue and 1st Street (3, 1). There is an initial beeper location at the corner of 2nd Avenue and 1st Street (2, 1). There are no final locations which means that Karel must pick up all initial beepers.

Solving a more interesting problem

The BeeperPickingKarel class defined in the previous section doesn’t do very much as yet. Let’s try to make it a little more interesting. Suppose that the goal is not simply to get Karel to pick up the beeper but to move the beeper from its initial position on 2nd Avenue and 1st Street to the center of the ledge at 5th Avenue and 2nd Street. Thus, your next assignment is to define a new Karel subclass that accomplishes the task illustrated in the world below:

The first three commands in the new program—the ones that move forward, pick up the beeper, and then move up to the ledge—are the same as before:

move();
pickBeeper();
move();

From here, the next step is to turn left to begin climbing the ledge. That operation is easy, because Karel has a turnLeft command in its standard repertoire. Executing a turnLeft command at the end of the preceding sequence of commands leaves Karel facing north on the corner of 3rd Avenue and 1st Street. If Karel then executes a move command, it will move north to the corner of 3rd Avenue and 2nd Street.

From here, the next thing you need to do is get Karel to turn right so that it is again facing east. While this operation is conceptually just as easy as getting Karel to turn left, there is a slight problem: Karel’s language includes a turnLeft command, but no turnRight command. It’s as if you bought the economy model and have now discovered that it is missing some important features.

At this point, you have your first opportunity to begin thinking like a programmer. You have one set of commands, but not exactly the set you need. What can you do? Can you accomplish the effect of a turnRight command using only the capabilities you have? The answer, of course, is yes. You can accomplish the effect of turning right by turning left three times. After three left turns, Karel will be facing in the desired direction. From here, all you need to do is program Karel to move over to the center of the ledge, drop the beeper and then move forward to the final position. A complete implementation of a BeeperTotingKarel class that accomplishes the entire task is in the editor.

Defining new methods

In your mental design of the program, Karel turns right when it reaches the top of the ledge. The fact that you have to use three turnLeft commands to do so is annoying. It would be much simpler if you could simply say turnRight and have Karel understand this command. The resulting program would not only be shorter and easier to write, but also significantly easier to read.

Fortunately, the Karel programming language and JavaScript both make it possible to define new commands simply by including new method definitions. Whenever you have a sequence of Karel commands that performs some useful task—such as turning right—you can define a new method that executes that sequence of commands. The format for defining a new Karel method has much the same as the definition of run in the preceding examples, which is a method definition in its own right. A typical method definition looks like this:

function <name>() {
    commands that make up the body of the method
}

In this pattern, <name> represents the name you have chosen for the new method. To complete the definition, all you have to do is provide the sequence of commands in the lines between the curly braces. For example, you can define turnRight as follows:

function turnRight {
    self.turnLeft();
    self.turnLeft();
    self.turnLeft();
}

Similarly, you could define a new turnAround method like this:

function turnAround() {
    self.turnLeft();
    self.turnLeft();
}

Thanks to the turnRight method, you don't have to call turnLeft three times to make a BeeperTotingKarel turn right.

There is, of course, one obvious difference between the definitions of the run and turnRight methods: run follows the public method signature pattern while turnRight follows the private method signature pattern. The difference between these two patterns is that public methods can be invoked from outside the class, while private methods cannot. It is also worth noting the difference in syntax for calling public and private methods. Public methods are usually called with this (this.run()), but most be called with self in private methods self.run(). self is a "workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions." (Crockford). this or self is a reference to the object. Public members, methods or variables, are attached to the object. And can be reference by the object itself or any other object. Private methods are called like so turnRight(). Since they should not be available outside of the object, they are not attached as public members. Instead, they are hidden using closures.

The run method needs to be public because the Karel environment needs to be able to issue a run command to get things going. By contrast, turnRight is used only inside the other code appearing within this class. That definition, therefore, can be private, and it is generally good programming practice to keep definitions private whenever possible. The reasons for this rule are difficult to appreciate until you have had a chance to work with larger programs, but the basic idea is that classes should try as much as possible to encapsulate information, which means not only to gather it together but also to restrict access to that information if possible. Large programs quickly become very complex in terms of the volume of detail that they encompass. If a class is well designed, it will seek to reduce that complexity by hiding as much extraneous detail as it can. This property is known as information hiding and is a cornerstone of the object-oriented philosophy.

At this point in your study of programming, you are not likely to find these arguments about encapsulation particularly convincing. Defining turnRight and turnAround in every program is certainly a bit of a pain, particularly in light of the fact that they are so useful. The difficulty, however, in making them more easily available lies in figuring out where to put those definitions. Declaring turnRight to be public in the definition of BeeperTotingKarel would not be much help. In an object-oriented language, the methods that specify the behavior of a class are encapsulated within that class. The turnRight method that appears within that class knows how to turn an instance of BeeperTotingKarel 90 degrees to the right, but that method cannot be applied to an instance of the Karel class or any its subclasses.

In some sense, what you really want to do is add turnRight and turnAround to the Karel class so that all subclasses will be able to use these undeniably useful commands. The problem with that strategy is that you don’t necessarily have the access to the Karel class necessary to make such a change. The Karel class is provided in karel.js, a JavaScript file hosted on this site, which is used by all visitors to this site. If you were to go and make changes to it, you might end up breaking someone else’s program, which would not endear you to the other visitors. What you can do, however, is define a new class that includes your new features as extensions. Thus, if you want to use turnRight and turnAround in several different Karel programs, you could define a new class that included these method definitions and then create your programs by extending that class. This technique will be covered in the next section.

This site includes a SuperKarel class that includes the methods turnRight and turnAround along with several other extensions that will make it possible for you to write much more exciting programs. The examples that follow extend SuperKarel to ensure that these methods are available. The other extensions are described in Chapter 6.

Decomposition

As a way of illustrating more of the power that comes with being able to define new methods, it’s useful to have Karel do something a little more practical than move a beeper from one place to another. The roadways around Palo Alto often seem to be in need of repair, and it might be fun to see if Karel can fill potholes in its abstract world. For example, imagine that Karel is standing on the “road” shown in the left-hand figure, one corner to the left of a pothole in the road. Karel’s job is to fill the hole with a beeper and proceed to the next corner. The diagram on the right illustrates how the world should look after the program execution.

If you are limited to the four predefined commands, the run method to solve this problem would look like this:

public void run() {
    move();
    turnLeft();
    turnLeft();
    turnLeft();
    move();
    putBeeper();
    turnLeft();
    turnLeft();
    move();
    turnLeft();
    turnLeft();
    turnLeft();
    move();
}

You can, however, make the main program easier to read by extending SuperKarel and then making use of the turnAround and turnRight methods. This version of the program appears in the editor.

The initial motivation for defining the turnRight method was that it was cumbersome to keep repeating three turnLeft commands to accomplish a right turn. Defining new methods has another important purpose beyond allowing you to avoid repeating the same command sequences every time you want to perform a particular task. The power to define methods unlocks the most important strategy in programming—the process of breaking a large problem down into smaller pieces that are easier to solve. The process of breaking a program down into smaller pieces is called decomposition, and the component parts of a large problem are called subproblems.

As an example, the problem of filling the hole in the roadway can be decomposed into the following subproblems:

  1. Move up to the hole
  2. Fill the hole by dropping a beeper into it
  3. Move on to the next corner

If you think about the problem in this way, you can use method definitions to create a program that reflects your conception of the program structure. The run method would look like this:

public void run() {
    move();
    fillPothole();
    move(); 
}

The correspondence with the outline is immediately clear, and everything would be great if only you could get Karel to understand what you mean by fillPothole. Given the power to define methods, implementing fillPothole is extremely simple. All you have to do is define a fillPothole method whose body consists of the commands you have already written to do the job, like this:

private void fillPothole() {
    turnRight();
    move();
    putBeeper();
    turnAround();
    move();
    turnRight();
}

Choosing the correct decomposition

There are, however, other decomposition strategies you might have tried. For example, you could have written the program as

public void run() {
    approachAndFillPothole();
    move();
}

where the approachAndFillPothole method is simply

private void approachAndFillPothole() {
    move();
    turnRight();
    move();
    putBeeper();
    turnAround();
    move();
    turnRight();
}

Alternatively, you might have written the program as

public void run() {
    move();
    turnRight();
    move();
    fillPotholeYouAreStandingIn();
    turnAround();
    move();
    turnRight();
    move();
}

where the body of fillPotholeYouAreStandingIn consists of a single putBeeper command. Each of these programs represents a possible decomposition. Each program correctly solves the problem. Given that all three versions of this program work, what makes one choice of breaking up the problem better than another?

In general, deciding how to decompose a program is not easy. In fact, as the problems become more complex, choosing an appropriate decomposition will turn out to be one of the more difficult aspects of programming. You can, however, rely to some extent on the following guidelines:

  1. Each subproblem should perform a conceptually simple task. The solution of a subproblem may require many commands and may be quite complex in terms of its internal operation. Even so, it should end up accomplishing some conceptual task that is itself easy to describe. A good indication of whether you have succeeded in identifying a reasonable task comes from the name you give to the method. If you can accurately define its effect with a simple descriptive name, you have probably chosen a good decomposition. On the other hand, if you end up with complex names such as approachAndFillPothole, the decomposition does not seem as promising.
  2. Each subproblem should perform a task that is as general as possible, so that it can be used in several different situations. If one decomposition results in a program that is only useful in the exact situation at hand and another would work equally well in a variety of related situations, you should probably choose the more general one.

Your first task is to solve a simple story-problem in Karel’s world. Suppose that Karel has settled into its house, which is the square area in the center of the world above.

Karel starts off in the northwest corner of its house as shown. The problem you need to get Karel to solve is to collect the newspaper—represented (as all objects in Karel’s world are) by a beeper—from outside the doorway and then to return to its initial position.

This exercise is extremely simple and exists just to get you started. You can assume that every part of the world looks just as it does in the diagram. The house is exactly this size, the door is always in the position shown, and the beeper is just outside the door. Thus, all you have to do is write the sequence of commands necessary to have Karel

  1. Move to the newspaper,
  2. Pick it up, and
  3. Return to its starting point.

Even though the program is only a few lines, it is still worth getting at least a little practice in decomposition. In your solution, include a private method for each of the steps shown in the outline.

Karel has been hired to repair the damage done to the Quad in the 1989 earthquake. In particular, Karel is to repair a set of arches where some of the stones (represented by beepers, of course) are missing from the columns supporting the arches, as in the world above.

Your program should work on the world shown above, but it should be general enough to handle any world that meets certain basic conditions as outlined at the end of this problem.

When Karel is done, the missing stones in the columns should be replaced by beepers.

World Dimensions:

Set the number of rows (streets) and columns (avenues).

Set the number of beepers Karel should start with in its bag.

Click on a link below for information on how to add the corresponding element to your world:

Initial Beeper Locations
Click on an intersection (+) to add or remove a beeper to that location.
Walls
Click between intersections (+) to add or remove a wall.
Final Beeper Locations
Click on an intersection (+) to add or remove a final beeper location.
Karel's Position
Click on an intersection (+) to set Karel's position.
Karel's Direction
Choose the direction Karel should start facing.
Nice job!
No result yet.