Note: This page is a locally cached version of http://www.otterbein.edu/home/fac/dvdjstck/CSC100/Notes/Lecture17.htm, © 1998-9 by David J. Stucki

Lecture 17: Top-Down Design, Karel, and Problem Solving

Problem: Karel signed up to run a hurdle race, but doesn't know how to do it. You job is to write a program that will help him. A picture of a sample race is shown here on the left with the route he should take drawn in orange. Karel is to run east along first street, starting at first avenue, until he reaches a corner with a beeper marking the end of the race. Along the way he may encounter hurdles (walls presenting an obstacle across first street). He must jump each hurdle in order to continue moving east towards the finish line. He can not jump several hurdles at once. In other words he must visit each intersection on first street as he travels east. The hurdles can vary in height, with the only limitation being that they are finite. You can assume that Karel starts out facing east.

So how do we solve this problem? It seems overwhelmingly complex, doesn't it? You likely wouldn't even know where to begin. This is exactly what top-down design is for. Let's see if we can decompose the problem in order to make it simpler. Remember there are two rules of thumb for doing this: look for repetitive parts, and look for distinct phases. So is there something that Karel will be doing many times in the course of running the race? Certainly. He will have to solve the problem of advancing one block east on first street. If he know how to do that, then would the problem be simpler? [Notice that this question is already dealing with step three of top-down design: combination.] Consider the following program segment:

while not-next-to-a-beeper do begin
         advance-one-block;
end;
turnoff;
This is a solution to the problem! The above fragment of code can be placed between the BEGINNING-OF-EXECUTION and END-OF-EXECUTION lines of the program. The only (sub)problem now is to figure out how to solve advance-one-block. However, this is a simpler problem than the original. We have made some progress.

Well, to advance one block, one of two situations will arise. Either there is no hurdle in front of Karel, in which case we can just tell him to move, or there is a hurdle that he must jump. Once again we can defer the complexity of jumping and solve this problem as follows:

define-new-instruction advance-one-block as begin
         if front-is-clear then begin
                  move;
         end
         else begin
                  jump;
         end;
end;
There are several things to note about this code. First, look at how Karel's vocabulary can be expanded. The DEFINE-NEW-INSTRUCTION facility allows us to define a new word in terms of words we already know (in most programming languages these are called procedures or functions). Also, we have only been able to solve this subproblem by creating a new subsubproblem, jump, which now needs to be solved. Fortunately, jump is simpler than advance-one-block. Finally, observe the use of semicolons and the words BEGIN and END. Why is there no semicolon after the first end? The rule for semicolons is that they are places after each instruction, except not before an ELSE.

So how do we teach Karel to jump? Here is a case where we can identify three distinct phases: first jump up, then cross over, then fall down. So here is a simple implementation of this decomposition:

define-new-instruction jump as begin
        turnleft;
        jump-up;
        cross-over;
        fall-down;
        turnleft;
end;
Why did we have Karel turnleft both at the beginning and at the end of the jump? This time the decomposition produced three subproblems, but they will each turn out to be simple enough to solve directly. To jump to the top of the wall Karel must repetitively move north and check to see if his right is clear. To fall down he simply moves until he gets to first street (his front will be blocked when he gets there). Here is the rest of the code:
define-new-instruction jump-up as begin
         while right-is-blocked do begin
                  move;
         end;
end;

define-new-instruction cross-over as begin
         turnright;
         move;
         turnright;
end;

define-new-instruction fall-down as begin
         while front-is-clear do begin
                  move;
         end;
end;

define-new-instruction turnright as begin
         turnleft;
         turnleft;
         turnleft;
end;

For a copy of the full program click here.