[Robot]
  Karel the Robot  

Conditionally Executing Instructions



Karel's Sensory Equipment

As you know, Karel has three video cameras, a microphone, a compass, and tactile sensors to help him stay out of trouble. He can request the following information from his sensory equipment: Each request will result in a true or false answer. We call such requests that are either true or false predicates.

Conditional Execution

Karel can check the predicates above using what is called an IF construct. These constructs can be used wherever instructions are used in a program. In the C / C++ language, there are two variations of the IF statement, the simple IF and the compound IF-THEN-ELSE.

Instruction Syntax
************************************
Explanation
if  (predicate)
{
        <then-clause statement(s)>
}
simple IF

if the predicate evaluates to true:
Karel will execute the instruction(s) in the then clause instruction block and then the instruction immediately following the then clause.
if the predicate evaluates to false:
Karel will not execute the instruction(s) in the then clause instruction block and will jump to the instruction immediately following the then clause.
if  (predicate)          
{
        <then-clause statement(s)>
}
else
{
        <else-clause statement(s)>
}
compound IF-THEN-ELSE

if the predicate evaluates to true:
Karel will execute the instruction(s) in the then clause instruction block and then the instruction immediately following the else clause. In other words, the then clause gets executed whereas the else clause is not and then the instruction following the if statement is executed.
if the predicate evaluates to false:
Karel will execute the instruction(s) in the else clause instruction block and then the instruction immediately following the else clause. In other words, the then clause is skipped and the else clause is executed; execution continues thereafter with the instruction following the if statement.

Here are some examples of IF statements. Note that nested IF's (that is, one IF statement inside another) can sometimes be confusing and it is important to make sure that those types of instructions really work as intended.

Example Explanation
if (nextToABeeper)
{
    PickBeeper();
}
Move();
Karel checks if a beeper is present on the current corner. If there is one, he will pick it up and move one step forward. If there is no beeper present, he will just move one step forward.
if (frontIsClear)
{
    Move();
}
else
{
    TurnLeft();
}
Karel will move ahead only if his front is not blocked by a wall. If his front is blocked, he will turn left instead.
void FaceNorthIfFacingSouth()
{
    if (facingSouth)
    {
        TurnLeft();
        TurnLeft();
    }
}
If Karel is facing South, this new command will turn him North. If Karel is not facing South, this new command will do nothing at all.
void Escape()
{
    if (frontIsClear)
    {
        Move();
        TurnLeft();
    }
    else
    {
        TurnLeft();
        Move();
    }
}
Karel would move and turn left if his front is clear. Otherwise, he would first turn left and then move. Note that if his front and left side were blocked, this new command would lead to an error shutoff.
void GiveOrTake()
{
    if (nextToABeeper)
    {
        if (anyBeepersInBeeperBag)
        {
            PutBeeper();
        }
        else
        {
            PickBeeper();
        }
    }
}
Karel would first check if he is next to a beeper. If so, he would add another beeper to the current corner, but only if there are any in his beeper bag. If he was next to a beeper but without beepers in his beeper bag, he would pick up the beeper from the current corner. If he was not near a beeper, he would do nothing.
void FaceNorth()
{
    if (notFacingNorth)
    {
        TurnLeft();
    }
    if (notFacingNorth)
    {
        TurnLeft();
    }
    if (notFacingNorth)
    {
        TurnLeft();
    }
}
Karel would check if he is facing a direction other than North. If so, he'll turn left. Karel will make the check twice more, each time turning left only if not already facing North.

Thus if Karel was initially facing North, he will do nothing. If Karel was initially facing East, he will make only one left turn. If Karel was initially facing South, he will make two left turns. If Karel was initially facing West, he will make a total of three left turns. At the end of executing this function, Karel is always facing North.


Clauses and Braces

Curly braces are needed to mark the beginning and end of then and else clauses only if these clauses contain more than one statement. If a clause has only one statement, the braces may (optionally) be omitted. Also, an IF statement is considered a single statement; this is true even of the compound IF statement. Here are the IF statements from above considered in terms of if they can be shortened by removing braces.

Original Code Code With Braces Omitted
  if (nextToABeeper)
  {
      PickBeeper();
  }
  Move();
  if (nextToABeeper)
      PickBeeper();
  Move();
  if (frontIsClear)
  {
      Move();
  }
  else
  {
      TurnLeft();
  }
  if (frontIsClear)
      Move();
  else
      TurnLeft();
  void FaceNorthIfFacingSouth()
  {
      if (facingSouth)
      {
          TurnLeft();
          TurnLeft();
      }
  }
Since the then clause consists of more than one statement, the braces cannot be omitted.
  void Escape()
  {
      if (frontIsClear)
      {
          Move();
          TurnLeft();
      }
      else
      {
          TurnLeft();
          Move();
      }
  }
Since the then and else clauses consist of more than one statement, the braces must be used.
  void GiveOrTake()
  {
      if (nextToABeeper)
      {
          if (anyBeepersInBeeperBag)
          {
              PutBeeper();
          }
          else
          {
              PickBeeper();
          }
      }
  }
  void GiveOrTake()
  {
      if (nextToABeeper)
          if (anyBeepersInBeeperBag)
              PutBeeper();
          else
              PickBeeper();
  }

Although the braces can be omitted, this might cause confusion. Feel free to leave the braces in place if you feel it makes the program easier to read.
void FaceNorth()
{
    if (notFacingNorth)
    {
        TurnLeft();
    }
    if (notFacingNorth)
    {
        TurnLeft();
    }
    if (notFacingNorth)
    {
        TurnLeft();
    }
}
void FaceNorth()
{
    if (notFacingNorth)
        TurnLeft();
    if (notFacingNorth)
        TurnLeft();
    if (notFacingNorth)
        TurnLeft();
}


Dangling ELSE's

There is one small danger in omitting curly braces from around clauses: the dangling ELSE. Unless clearly delimited by curly braces, an else attaches itself to the last if that doesn't have an else. This can cause problems, for example:

You thought you wrote this: ... but this is how the computer sees it:

    if (nextToABeeper)    
        if (facingNorth)
            TurnLeft();
    else
        PutBeeper();
    Move();

    if (nextToABeeper)    
        if (facingNorth)
            TurnLeft();
        else
            PutBeeper();
    Move();

Adding curly braces to make clear where the end of the first IF statement's then clause is will solve the problem of the dangling ELSE, as illustrated below:


    if (nextToABeeper)    
    {
        if (facingNorth)
            TurnLeft();
    }
    else
        PutBeeper();
    Move();


Multiple Alternatives

The IF-THEN-ELSE provides an obvious way of selecting which of two alternatives are to be performed in a program. If there are more than two alternatives, nested IF-THEN-ELSE's can be used. Usually we indent these nested IF-THEN-ELSE's in such a way as to highlight that one of a set of mutually exclusive alternatives is to be executed. An example will make things clearer:

Example: Explanation:

    ...
    TurnRight();

    if (facingNorth)    
        TurnLeft();
    else if (facingEast)
    {
        Move();
        TurnLeft();
    }
    else if (facingSouth)
        PickBeeper();
    else
        PutBeeper();

    PickBeeperIfPresent();  
    ...
In the code fragment to the left, we see that between the TurnRight() instruction and the PickBeeperIfPresent() instruction one of four alternatives will be executed. Which of the mutually exclusive alternatives is done depends on the direction Karel is facing when he enters this section of code. If Karel is facing to the North, he will turn left before executing the PickBeeperIfPresent() instruction. If Karel is facing to the East, he will move one block further to the East and then turn left; thereafter he will execute the PickBeeperIfPresent() instruction. Similarly, if Karel is facing to the South, the alternate action to be performed is picking a beeper; if Karel is facing any other direction (of course, the only direction left must be West), Karel will put down a beeper.

Notice that curly braces were needed to enclose the second alternative: a Move() followed by a TurnLeft(). This is the then clause of the if (facingEast) statement and, since it contains more than one statement, needed the curly braces.



Prior Topic       |       Next Topic  

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