Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race,...

34
Mile-long hurdle race pose that we want to program Karel to run a one-mil g hurdle race, where vertical wall sections represe dles. The hurdles are only one block high and are domly placed between any two corners in the race rse. One possible race course is shown below.

description

Jumping up between corners, whether a hurdle was between them or not, would slow Karel down. Instead, program Karel to move straight ahead when it can, and to jump over hurdles only when it must. The program could then consist of 8 AdvanceACorner() instructions. The definition of AdvanceACorner() can be written using stepwise refinement as follows:

Transcript of Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race,...

Page 1: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Mile-long hurdle race

Suppose that we want to program Karel to run a one-milelong hurdle race, where vertical wall sections representhurdles. The hurdles are only one block high and are randomly placed between any two corners in the race course. One possible race course is shown below.

Page 2: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Strategy?

Karel could run this race by jumping up between every pair of corners. Is this an appropriate strategy?

Page 3: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Jumping up between corners, whether a hurdle was between them or not, would slow Karel down. Instead, program Karel to move straight ahead when it can, and to jump over hurdles only when it must. The program could then consist of 8 AdvanceACorner() instructions. The definition of AdvanceACorner() can be written using stepwise refinement as follows:

Page 4: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

void AdvanceACorner(){

if (frontIsClear)Move();

elseJumpHurdle();

}

Notice we have used a new command JumpHurdle()that must now be defined.

Page 5: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

We continue our refinement by defining JumpHurdle() to be

void JumpHurdle(){

JumpUp();Move();JumpDown();

}

Page 6: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

To finish the problem, we write JumpUp()and JumpDown()

Void JumpUp() void JumpDown(){ {

TurnLeft(); TurnRight();Move(); Move();TurnRight(); TurnLeft();

} }

Page 7: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Instructions that repeat

• Karel often has to repeat instructions. For example, to run the hurdle race, the instruction AdvanceACorner()had to be repeated 8 times.

• There are three instructions built into Karel’s vocabulary that allow an instruction to be repeated. These are iterate , while, and do-while.

Page 8: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

iterateiterate is used when it is necessary to have Karel perform an instruction a certain number of times.

We previously handled this problem by writing the instruction as many times as needed. The new instruction has the following form:

Page 9: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

iterate (iteration-amount) { <loop body statement(s)> }

where iteration-amount is the number of times the statements in the loop body (statements between curly braces { }) will be performed.

Page 10: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

For example, the solution of the hurdle race problem can now be written as one of the following:

int main() int main() { { TurnOn(); TurnOn(); iterate (8) AdvanceACorner(); { AdvanceACorner(); AdvanceACorner(); AdvanceACorner(); } AdvanceACorner(); TurnOff(); AdvanceACorner(); } AdvanceACorner(); AdvanceACorner(); AdvanceACorner(); TurnOff(); }

Page 11: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Examples:

void TurnRight(){ iterate (3) { TurnLeft(); }}The primitive instruction TurnLeft(); is repeated three times, which is equivalent to a right turn.

Page 12: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

void Harvest1Row(){ PickBeeper(); iterate (4) { Move(); PickBeeper(); }}Karel would pick a single beeper and then repeat the sequence Move(); PickBeeper(); four times. The new instruction therefore would execute five PickBeeper() instructions and four Move()'s.

Page 13: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Curly braces are needed to mark the beginning and end of a loop body only if the body contains more than one statement. If the body consists of only one statement, the braces may (optionally) be omitted. Also, an ITERATE statement is considered a single statement.

Original Code Code With Braces Omitted void TurnRight() void TurnRight(){ { iterate (3) iterate (3) { TurnLeft(); TurnLeft(); } }}

Page 14: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

void TraverseSquare() void TraverseSquare(){ { iterate (4) iterate(4) { { iterate (5) iterate(5) { Move(); Move(); TurnLeft(); } } TurnLeft(); } }}

(NOTE: The iterate statement is NOT a standard C / C++ statement, although it can easily be simulated using the standard for statement. The iterate statement has been introduced to simplify Karel programming.)

Page 15: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

while

There are many situations where Karel needs to repeat an instruction but it is not yet known how often. For example, if we wish for Karel to pick up a pile of beepers of arbitrary size, he needs to repeatedly execute the PickBeeper() command, but because we do not know in advance the number of beepers in the pile, we do not know exactly how often to execute that command.

Page 16: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

The WHILE statement is made-to-order for this situation: you can use it to tell Karel to repeat something while a certain predicate is true; for example to pick upbeepers while there are any left to pick up. while (predicate) { <loop body statement(s)> }

The predicate that appears between the parentheses of the WHILE statement comes from the same list of predicates that Karel can use in an IF statement.

Page 17: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• Karel executes a WHILE by first checking the predicate.

• If the predicate is true, then the loop body is executed and Karel loops back to the predicate to check it again.

• This continues over and over as long as the predicate evaluates to true.

• If the predicate evaluates to false, Karel is finished with the WHILE statement and begins executing the instruction that immediately follows the WHILE statement.

Page 18: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• NOTE: If the predicate is initially false the statement(s) in the loop body will not be executed at all.

• For this reason, WHILE loops are sometimes called zero-or-more times loops.

• Also note that, just as with ITERATE statements, curly braces are needed to mark the beginning and end of a loop body only if the body contains more than one statement.

Page 19: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Examples:

void ClearCornerOfBeepers(){ while (nextToABeeper) PickBeeper();}

Karel would pick up all beepers on the current corner, regardless how many there are (if it is a finite number, at least).

Page 20: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Building a WHILE Loop• Step 1: Identify the one test that must be true

when Karel is finished with the loop.In the above problem, Karel must pick all beepers

on the corner. If we consider only tests that involve beepers, we can choose among four:

anyBeepersInBeeperBag, noBeepersInBeeperBag, nextToABeeper, and notNextToABeeper

Which one is the test we want?

Page 21: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• Step 2: Use the opposite form of the test identified in step 1 as the loop predicate.

This step implies that we should use nextToABeeper. The WHILE instruction continues to execute the loop body as long as the test is true and stops when it is false.

Page 22: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• Step 3: Do whatever is required before or after the WHILE is executed to ensure we solve the given problem.

In this example, we have to do nothing before or after the loop. However in other situations, we may miss one iteration of the loop and have to “clean things up,” which can be done either before or after the WHILE.

Page 23: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• Step 4: Do the minimum that is needed to ensure that the test eventually evaluates to false so that the WHILE loop stops.Something within the body of the loop must

allow the test eventually to evaluate to false or the loop will run forever.

This implies that there must be some instruction (or sequence or instructions) within the loop that is related to the test.

Thus in our example, since we are testing for nextToABeeper we must pick one (and only one) beeper somewhere in the loop.

Page 24: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Apply these four steps to a new problem. Karel is somewhere in the world facing south. One beeper is on every corner between Karel’s current position and the southern boundary wall. There is no beeper on the corner on which it is currently standing. Write a new instruction ClearAllBeepersToWall, to pick all the beepers.To solve any problem, ask questions:What do we know about Karel’s initial situation?

Karel is facing southKarel is an unknown distance from the southern boundary wallEach corner between Karel and the southern boundary wall has one beeper.

Page 25: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Does any of this information provide insight toward a solution?

Yes – Karel can travel forward until it reaches the southern boundary wall. It can pick a beeper from each corner as it travels.

What Karel instruction can we use to keep Karel traveling southward until it reaches the southern boundary wall?

Since traveling to the southern boundary wall requires an unknown number of move instructions, we can use a WHILE loop.

Page 26: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Four Step Process

• Step 1: Identify the one test that must be true when Karel is finished with the loop.Karel will be at the southern boundary wall, so

the test frontIsBlocked will be true.

Page 27: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• Step 2: Use the opposite form of the test identified in step 1.The opposite of frontIsBlocked is

frontIsClear.

• Step 3: Do whatever is required before or after the WHILE is executed to ensure we solve the given problem. Since Karel is already facing south, we do not have to do anything.

Page 28: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• Step 4: Do the minimum that is needed to ensure that the test eventually evaluates to false so that the WHILE loop stops.Karel must move forward one block then pick a beeper.

Page 29: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

Based on this discussion, we can write the following new instruction:

void ClearAllBeepersToWall(){

while (frontIsClear){

Move();PickBeeper();

}}

Page 30: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

A while loop can occur in a while loop:

void PickBeepersToWall(){ while (nextToABeeper) PickBeeper(); while (frontIsClear) { Move(); while (nextToABeeper) PickBeeper(); }}The logic of these nested WHILE statements has Karel pick up all beepers between him and the wall ahead of him, including beepers on Karel's beginning street corner. Karel stops in front of the wall.

Page 31: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

do WhileThe DO...WHILE statement is not used a great deal. Nonetheless, there are occasional circumstances where we want to perform the body of a loop at least once and then check a predicate. The DO...WHILE statement allows us to do this. We call this construct a post-test or exit-controlled loop.

do { <loop body statement(s)> } while (predicate);

Page 32: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• The predicate that appears between the parentheses of the DO...WHILE statement comes from the same list of predicates that Karel can use in an IF statement.

• Karel executes a DO...WHILE by first executing the loop body. After completing the loop body, the predicate is checked. If the predicate is true then Karel loops back and executes the loop body again.

• This continues as long as the predicate evaluates to true.

• If the predicate evaluates to false, Karel is finished with the DO...WHILE statement and begins executing the instruction that immediately follows the DO...WHILE statement.

Page 33: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

• NOTE: Since the loop body is executed at least once, DO...WHILE loops are sometimes called one-or-more times loops.

• Also note that, just as with ITERATE statements, curly braces are needed to mark the beginning and end of a loop body only if the body contains more than one statement.

• However for this statement it is customary to always include the curly braces.

• Finally, note the need for a semicolon at the end of the statement.

Page 34: Mile-long hurdle race Suppose that we want to program Karel to run a one-mile long hurdle race, where vertical wall sections represent hurdles. The hurdles.

void FaceWestIfFacingSouth(){ if (facingSouth) { do { TurnLeft(); } while (notFacingWest); }}

If initially facing South, Karel will turn left until he is facing to the West.