The magazine of the Melbourne PC User Group
An Introduction to Programming with Karel the Robot
Trevor Gosbell |
|
Computer programming is an absorbing and challenging hobby and a valuable
occupational skill. It helps develop many useful intellectual abilities,
including analytical thinking, creativity, and problem-solving. But most
importantly, computer programming is fun.
Welcome to the first in a series of articles intended for people with a moderate
level of computer experience but little or no knowledge of programming. Let's
say you know what files and folders are, you can use a word processor, you don't
need detailed instructions on how to install software, and if I say "Run Program
X" you've got a pretty good idea where Program X is and how to get it going.
That's all you need - no expertise required.
This is an introduction to computer programming, specifically object-oriented
programming in the Java programming language. In the example programs and
exercises you will program a robot to carry out various tasks. Although it is
possible to do all of the programming exercises on paper (writing programs out
and "running" them by hand), it is more fun to use a robot simulator on your
computer. I will assume that you have installed the Karel J. Robot simulator -
see "Cooking Up a Programming Environment" for more information.
In this article we will learn about the robot world, cover the basics of
programming a robot, and get you started on your own programming tasks.
Get To Know Your Robot
Meet Karel the Robot. Karel and the other robots like it exist in a flat world
of avenues (running north-south) and streets (running east-west), making a grid
with intersections as illustrated in Figure 1. Note that the streets and avenues
are numbered so it is possible to identify an intersection by the street and
avenue number. An impenetrable wall runs along the robot world to the west and
south, otherwise robots may wander the streets and avenues. |

Figure 1 |
Robot Abilities
A robot is able move in the direction it is facing. Each time it moves, a robot
moves from one intersection to the next - the length of exactly one block. For
example, if a robot is facing north (towards the top of the screen) at the
corner of 4th Avenue and 2nd Street and it is told to move, it will move to the
corner of 4th Avenue and 3rd Street.
A robot can also turn 90 degrees at a time, allowing it to face the four major
compass points: north, south, east, and west. But is is not able to turn to the
points in between - for instance it can't face south-east. When it turns a robot
stays at the same location. For example if a robot is facing north at the corner
of 4th Avenue and 3rd Street and it is told to turn left, it will turn to face
west but will stay standing at the corner of 4th Avenue and 3rd Street.
A robot can also manipulate objects called "beepers". Beepers are small plastic
discs that emit a soft beep. If there are any beepers in the same location as
the robot, it can detect the beeping. A robot can pick up a beeper if there is
at least one at the intersection where it stands. A robot can put down a beeper
if it is carrying at least one beeper.
Setting Tasks for a Robot
With these abilities available, we can program a robot to carry out tasks in the
robot world. Let's have a look at a robot task written in the Java language. See
Listing 1
Listing 1 -- a robot task
1. Robot karel = new Robot(1, 2, East, 3);
2. karel.move();
3. karel.putBeeper();
4. karel.move();
5. karel.move();
6. karel.move();
7. karel.turnLeft();
8. karel.putBeeper();
9. karel.move();
10. karel.move();
11. karel.move();
12. karel.putBeeper();
13. karel.move();
14. karel.move(); |
Notice that each command ends with a semicolon. This is part of the syntax of
Java and it means "the current command ends here, anything after this belongs to
the next command".
Let's look at the task line by line.
The first line makes a robot and positions it in the robot world. We need to
read it back to front as follows:
- new Robot - means make a new robot
- (1, 2, East, 3) - put the new robot at the corner of 1st Avenue and 2nd Street,
make it face east, and give it 3 beepers to carry
- Robot karel = - name the new robot "karel". The equals sign is used to assign
the name karel to the new robot that we have requested. Note that the name karel
can only refer to a robot because it has the "Robot" prefix. This means that in
this task we can't make a non-robot object, say a bicycle, and call it karel -
karel can only be a robot.
At line 2 we get our robot to move one space in the direction it is facing.
Notice that we give the robot a command by using its name, putting in a dot,
then adding an instruction. In this case it's like saying in English "Karel,
move". In normal English, line 3 means "Karel, put down a beeper here."
In lines 4, 5, and 6 karel is told to move. At line 7 the robot is told to turn
exactly 90 degrees to its left. It has not moved from where it was at the end of
line 6, but it is now facing in a new direction.
Hopefully you can follow the pattern of the remaining commands. Before you go
any further, try to work out what the robot does in this task. It will be easier
if you sketch it out on a piece of paper.
Rev It Up
To run this task as a program, follow these steps:
- Start up BlueJ
- Load the project "example01" from your working folder (choose
Project|Open Project... and move to your working folder). You should see a
screen similar to Figure 2.
- Right-click on the box labeled "Example01" and choose the option "new
Example01()", which opens the box in Figure 3.
- Change the "Name of Instance" field to "test" and click "OK". Figure 4 shows the
new "test" box at the bottom of the screen.
- Right-click on the "test" box and the second option is "void task()" - this is
our robot's task, so click this and see what happens.
|

Figure 2 |

Figure 3 |

Figure 4 |
A window opens to display the robot world and another opens to display a "trace"
of the program status. If your screen is like mine the trace window will overlap
the robot world window, so just click on the title bar of the latter so you can
watch the robot move. The end result is shown in Figure 5.
Have a look at the trace output and compare it with Listing 1. Notice that as
each line in Listing 1 is executed the robot does something and the result of
that action appears as an entry in the trace. This is an important point -
computers do things very quickly but they only do one thing at a time, so each
command builds on the result of the previous command.
Peek Under the Hood
Now that we've seen the robot in action, let's look at the code.
Close down the robot world and trace windows and return to the project window in
BlueJ. Double-click on the "Example01" box and the edit window opens showing the
code in Listing 2.
Listing 2 -- The whole program
import kareltherobot.*;
public class Example01 implements RobotTask
{
public void task()
{
World.reset();
World.setTrace(true);
World.setVisible(true);
Robot karel = new Robot(1, 2, East, 3);
karel.move();
karel.putBeeper();
karel.move();
karel.move();
karel.move();
karel.turnLeft();
karel.putBeeper();
karel.move();
karel.move();
karel.move();
karel.putBeeper();
karel.move();
karel.move();
}
} |
This is the "source" code for the scenario we've just watched the robot acting
out. Most of it will be familiar to you from the robot task instructions in
Listing 1, but there is some new stuff there:
- The first line isn't actually part of the program, rather it makes sure that all
of the information about robots is available to the program. Details about how
to make a robot and what a robot can do are stored in a special package called "kareltherobot",
so we need to "import" it into our program.
- The next line indicates that this is a program that describes a task that we
want to give to a robot (a "RobotTask"). This is also where the program is named
and (with more devastating originality) I have decided to call it "Example01".
- The actual Example01 program starts on the next line with the left hand curly
bracket {, and the end of the program is marked by the matching right hand curly
bracket } on the last line.
- The command public void task() indicates the start of the robot's task. The
commands that make up the task are contained in another matching set of curly
brackets {}.
- The first three commands of the robot task do some housekeeping: World.reset()
clears everything off the robot world (a bit like clearing all of the playing
pieces off a game board before starting a new game), World.setVisible(true)
displays the robot world, and World.setTrace(true) makes the trace window
visible.
- The remaining commands have already been discussed above.
Fiddle With the Engine
I get a bit frustrated by that trace window popping up in front of the robot
world. So let's get rid of it.
Change the line World.setTrace(true); to read World.setTrace(false); and click
the Compile button. Watch the status bar at the bottom of the
window and the message "Class compiled - no syntax errors" should soon appear.
Return to the BlueJ project window and you'll notice that the "test" object is
no longer available. Because the source code has changed, the "test" object is
no longer valid. So to make a new one go through this dance again:
- Right-click on "Example01" and choose the option "new Example01()".
- Change the "Name of Instance" field to "test" and click "OK".
- Right-click on the "test" box and select the "void task()" option.
Look Mum - no trace!
Indulge Your Inner Vandal
Let's do some deliberate damage and see how well the robot copes.
Double-click on the Example01 box to open the editor window. Now remove the
semicolon from the end of the World.reset() command - remember that a semicolon
is used to indicate where one command ends and another begins, so without one on
the end of this command we have made a syntax error. Click Compile and notice
the next line gets highlighted and the status bar says "';' expected". The
compiler has noticed something fishy here and has put the highlight roughly near
the trouble spot. Replace the semicolon and compile again - there should be no
problems this time.
|

Figure 5 |

Figure 6 |

Figure 7 |
Change the command karel.turnLeft(); to karel.turnRight(); and click Compile.
This time the editor highlights the trouble spot exactly and the status line
says "cannot resolve symbol - method turnRight". The compiler doesn't recognise
the word "turnRight". That seems very odd, but it's correct - there is no
command to make the robot turn to the right! So this is another syntax error.
(By the way, why don't robots need a turnRight() command? See "A harder task"
below for a clue.)
Restore the karel.turnLeft() command, then in the command Robot karel = new
Robot(1, 2, East, 3); change "East" to "North". Try to compile it - hey, no
errors! Close the editor window, make a new Example01 object in the main window,
then right-click and select void task(). This time the robot starts moving
north, places two beepers and - smacks into a wall! The trace window appears and
says that an "Error shutoff" has occurred.
Why did the compiler let this error through? Remember that computers are
incredibly stupid - they can't work out what you're trying to do. As long as the
syntax of your commands are legal, your program will compile. This is not an
error of syntax - all of the commands are legal and the grammar is correct. The
error was in the meaning of the commands. Such errors are commonly known as
run-time errors because they only appear when you run the program. Compilers can
not detect run-time errors.
Open up the editor again and alter the same line so that it reads Robot karel =
new Robot(1, 2, East, 1);. This time the robot is facing east so it won't run
into a wall and everything should be fine. What else could go wrong? To find
out, compile and run it.
The robot has run out of beepers so it can't put down any when it is told to -
another run-time error. To generalise, run-time errors occur when a legal
command can't be completed. So if you tell the robot to move when it's facing a
wall, the move command can't be completed. If you tell the robot to pick up a
beeper but there isn't one available at its current location, then the pick up
command can't be completed.
Some Tasks For You
Getting a different view
What would you need to change in Example01 to hide the robot world and only make
the trace window visible? Try it and see if you're right. Is it possible to make
the program work with no output at all?
Extending the robot task
In the Example01 program the robot places beepers on three corners of a square.
Adjust the program so that the robot marks all four corners of the square with
beepers (Figure 6).
A harder task
Adjust the Example01 program so that the robot makes a diagonal line of beepers
that starts at the corner of 1st Avenue and 1st Street and ends at the corner of
4th Avenue and 4th Street (Figure 7).
Hint
To do this the robot will need to turn both left and right but robots have no
turnRight() command. What happens if you get the robot to turnLeft() more than
once?
Wrap up
This article:
- introduced Karel the Robot and the robot world
- outlined the four abilities of robots: move(), turnLeft(), putBeeper(), and
pickBeeper()
- showed how to program a task for the robot to perform
- showed how to compile and run a robot program
- explained the difference between syntax errors and run-time errors
In the next installment, we will cover how to teach new commands to the robot.
Cooking Up A
Programming Environment
The Ingredients
To follow along with the programming exercises, you will need four things:
1. Java Standard Edition
Java is a programming language that is made freely available by the Sun
Corporation. It's usually best to get the latest possible version, which
at the time of writing is 1.4.2. It can be downloaded from
http://java.sun.com/j2se/1.4.2/download.html. Java weighs-in at well
over 40 megabytes so this month it has also been made available on the
October Monthly CD (see pages 44-45).
System requirements are available at
http://java.sun.com/j2se/1.4.2/install-windows.html. Note that Windows
95 is not supported by Java version 1.4.2, so if that's your platform
you'll need to grab an earlier version from the
http://java.sun.com/.
2. BlueJ
BlueJ is a programming editor developed at Monash University to help
people learn to program. It can be downloaded from
http://www.bluej.org/download/download.html and it can also be found
on the October Monthly CD.
3. Karel J Robot
Karel J Robot is the robot simulator that we will be programming.
Downloaded it from
http://csis.pace.edu/~bergin/KarelJava2ed/karelpremier.zip.
4. Examples
A zip file containing the examples from the article is available from my
Web site at
http://member.melbpc.org.au/~tgosbell/.
The Method
Add your ingredients in order. First install Java, by running
j2sdk-1_4_2_01-windows-i586.exe. Extra installation instructions are
available at
http://java.sun.com/j2se/1.4.2/install-windows.html if
necessary. Take note of where you choose to install the program
(maybe C:\j2se1.4.2\) - remember this and we'll refer to it as the
Java Folder.
Next install BlueJ - run bluejsetup-130.exe. Extra installation
instructions are available at
http://www.bluej.org/download/install.html. The installer will
ask where you want BlueJ to reside (maybe C:\bluej\) - make a note
again, and we'll call this the BlueJ Folder. The BlueJ installer may
also ask for the name of your Java Folder.
Unzip karelpremier.zip into a folder that we'll call (with
breathtaking originality) the Karel Folder. |

Figure 1 |
Finally unzip karel-example01.zip into a folder, which we'll call
the Working Folder.
Now start up BlueJ and you will be presented with the BlueJ Project
Window (Figure 1). Celebrate - it works! On the menu choose Tools|
Preferences, then choose the Libraries tab in the Preferences
window. Click "Add", navigate to the Karel Folder and select the
file "KarelJRobot.jar". Your entry should show up as in Figure 2.
You will now need to exit and restart BlueJ and you are ready to
start programming. |

Figure 2 |
|
About Compiling
The authors of "The Structure and Interpretation of Computer Programs"
http://mitpress.mit.edu/sicp/
say that "programs must be written for people to read, and only
incidentally for machines to execute." At first you may find this
incredibly hard to believe because very few computer programs look like
attractive bedtime reading.
But it's true - programming languages exist for our convenience. Computers
can't run programs in the form that we write them, programs must first be
translated into machine language. Machine code looks like a random
sequence of "0"s and "1"s, which is why it is often called binary
code.
Programming languages exist to make programming more efficient - one
command in a programming language may correspond to dozens of commands in
machine code. Think how much longer it would take to program all those
extra commands - and how many more mistakes you'd make - if you had to
write every single command in machine language. Which is easier to read
and write - the sequence of "0"s and "1"s or Java? At least Java looks
remotely like English.
The process of converting a program written in a programming language (the
"source code") into the equivalent program in machine language (the
"binary" or "object code") is usually called "compiling" and the program
that does the work is called a "compiler". The first step in compiling is
to check that the syntax of the source code is all correct because the
compiler can only translate source code that it "understands". If there
are no errors in the source code, the translation takes place and a new
binary file is produced.
At last we have a binary version of the file, which the computer is able
to execute.
Don't forget that whenever a change is made to the source code, it must be
compiled again or the binary file will not reflect the most recent
modifications. That explains why we seem to do a lot of compiling in this
article!
|
Reprinted from the October 2003 issue of PC Update, the magazine of Melbourne PC User Group, Australia
|