Computer Science E50a Wednesday Section . 7:30 . Emerson 106

TF: Alix Marchandise-Franquet September 30th, 1998

A new built-in class of robot: Robot

What more can robots of that class do?
They can sense more things than the basic ur_Robot:

  1. the direction they are facing (East, West, North, South)
  2. the presence/absence of wall segments
  3. the presence/absence of beepers on their corner
  4. the presence/absence of robots (of any class) on their corner
  5. the presence/absence of beepers in their bag
Our old friend the ur_Robot could already sense number 2, 3 and 5. However, it only used this information to shut itslef off in case it attempted to pick an unexistent beeper for example.
Now, with the more sophisticated Robot, you have access to these informations through new built-in functions. Each of these can have one of two values: true or false.


Negation !

You have a new tool for your programs: the possibility of negating a value, ie changing a true into a false and a false into a true. This means that you can get even more information regarding your Robot. By adding an exclamation mark ! in front of a condition, you can test for its negation.
For example, !frontIsClear() means that the front is blocked.


If ...

Now that you have these new conditions that you can test (whether the Robot is facing East or not etc...), you need a way to do so. This is where if is useful. This lets you have the robot execute some instructions only in certain situations (for example, you only want your robot to try picking up a beeper if there is one on his corner, otherwise you will get an error shutoff).

if ( condition )
{
        instructions to be executed if the condition is true
}

Three important things:

If ... else ...

You can think of the else as "otherwise": if A do B, otherwise (ie if not A) then do C, where A is a condition that is tested, and B and C are sets of instructions.
if ( condition )
{
        instructions to be executed if the condition is true
}
else
{

        instructions to be executed if the condition is false
}

You can have nested if ... else statements. Example:
if (Karel.anyBeepersInBeeperBag())
{
        // Karel only looks in here if there are Beepers in the bag
        //otherwise it skips to the final else
        if (Karel.nextToABeeper())
       {
               // at this point, Karel must have beepers in its bag
               // and there must be a beeper on the corner

              Karel.pickBeeper();
              Karel.turnLeft();
       }
       else
       {
               // at this point, Karel has beepers in its bag,
               // but there are no beepers on the corner

              Karel.putBeeper();
              Karel.turnRight();
       }
}
else
{
        // Karel will only turnLeft() and turnOff() if
        // it had no beepers in its beeper bag

       Karel.turnOff();
}

Note:
You don't necessarily need an else clause. Maybe you want Karel to turnLeft if it is facing East, but stay in the same position otherwise. Also, if in the if clause, you turnOff Karel, then you don't need an else either because you know that it will not execute any other instruction anyway. We will see another case later today.


Making your own conditions

Remember that last week, you were able to define new instructions for the robots.
This week, you learned how to define new conditions. These will also have one of two values: true or false (in lower case). These values are returned by the function you define. Since we are now returning values, we use a new word: Boolean where we used to write void in our new definitions. Boolean means that the function will return true or false. To build new conditions, we start from the basic ones (and their negations) that are built in the Robot class (see above).

Example with appropriate comments and indentation:

// A robot of class myRobot can turn around,
// figure out if it is on a busy corner and if its back is blocked
class myRobot : Robot
{
       Boolean busyCorner();
       Boolean backIsBlocked();
       void turnAround();
};

// Makes the robot face the opposite direction
void myRobot :: turnAround()
{
       turnLeft();
       turnLeft();
}

// Returns true if there is at least one beeper and at least one other robot
// on the robot's corner, returns false otherwise
Boolean myRobot :: busyCorner()
{
       if (nextToABeeper())
        {
               if (nextToARobot())
              {
                     return true;
              }
       }
       return false;
}

// Returns true if there is a wall behind the robot, false otherwise
Boolean myRobot :: backIsBlocked()
{
       turnAround();
       if ( !frontIsClear())
       {
               return true;
       }
       return false;
}


More on Problem Set 1

Pencil and Paper
You may very well test your answers to these problems on the computer.

Problem 2: it would be a good idea to comment the program (ie "now the robot is facing West"). This should help you. Also, watch for the curly braces (where should they really be?).

Problem 3: check if there are any unnecessary conditions, testing for things that are always true at that point in the program (for example, testing if there are any beepers in the beeper bag when you have just picked up a beeper!)

Problem 4: as long as you end up in the same state as the one you started in, you may do whatever you wish: turnaround, put beepers, pickbeepers etc... See if you can find a way to have the robot count the number of beepers.

Programming
One important thing: there isn't only one way of solving these problems. As long as your program is structured and does what it is supposed to do, you should be fine.
For problems 6, 7 and 8, you will have to create the world files yourself. For 7 and 8, the worlds are drawn in the Karel++ book and you simply need to make the corresponding .wld file.

Problem 6: create 6 different worlds to test it, one for each of the following cases: 0, 1, 2, 3, 4 or 5 beepers on the corner on which the root is standing. Try to determine what is common to some of the situations. Which predicates should you use?

Problem 7: this is a modification of the harvesting problem in the text. There are many ways of harvesting this diamond-shaped area. Pick the one you find the simplest. If you can't come up with any, look at the way they solved the similar problem in the book and try to adapt it.

Problem 8 (grad students and extra credit): As usual, try to break up this problem into smaller problems. How do you know when you are at the top of a barrier? At the bottom? At the end of the race?