[Robot]
  Karel the Robot  

Repeatedly Executing Instructions



Repeating instructions: ITERATE

Karel has a simple way to repeat (or iterate) instructions any number of times without us having to retype the commands. That new construct is defined using the reserved word iterate.

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


Example Explanation
void TurnRight()
{
    iterate (3)
    {
        TurnLeft();
    }
}
The primitive instruction TurnLeft() is repeated three times, which is equivalent to a right turn.
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.

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. Here are some example ITERATE statements considered in terms of if they can be shortened by removing braces.

Original Code Code With Braces Omitted
void TurnRight()
{
    iterate (3)
    {
        TurnLeft();
    }
}
void TurnRight()
{
    iterate (3)
        TurnLeft();
}
void TraverseSquare()
{
    iterate (4)
    {
        iterate (5)
        {
            Move();
        }
        TurnLeft();
    }
}
void TraverseSquare()
{
    iterate (4)
    {
        iterate (5)
            Move();
        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.)


Repeating instructions: 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 since we do not know in advance the number of beepers in the pile, we do not know exactly how often to execute that command.

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 up beepers while there any 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. Karel executes a WHILE by first checking the predicate; if the predicate is true then the loop body is executed and the Karel loops back to the predicate to check it again. This continues while 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.

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.

Example Explanation
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).
void FaceNorth()
{
    while (notFacingNorth)
    {
        TurnLeft();
    }
}
Karel will turn left as often as necessary in order to be facing North at the end of executing this function. Note that if this function is invoked when Karel is already facing North, zero turn lefts will occur. Note also how much shorter this implementation of FaceNorth() is compared to the implementation that used a series of three IF statements.
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.
This example also illustrates that braces can be omitted if the loop body consists of only one statement.

Repeating instructions: DO...WHILE

The 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);

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.

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.

Example Explanation
void FaceWestIfFacingSouth()
{
    if (facingSouth)
    {
        do
        {
            TurnLeft();
        } while (notFacingWest);
    }
}
If initially facing South, Karel will turn left until he is facing to the West.
void PickBeepersToWall()
{
    if (nextToABeeper)
        do
        {
            PickBeeper();
        } while (nextToABeeper);
    while (frontIsClear)
    {
        Move();
        if (nextToABeeper)
            do
            {
                PickBeeper();
            } while (nextToABeeper);
    }
}
The logic to the left 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. Note the need to guard the DO...WHILE statements with IF statements to prevent an error shutoff if the corners do not contain any beepers.



Prior Topic       |       Next Topic  

[MTSU]  | CS  | [Home] Return to Karel home page
(Credits and Copyrights)