A document from MCS 275 Spring 2023, instructor David Dumas. You can also get the notebook file.

MCS 275 Spring 2023 Worksheet 4

  • Course instructor: David Dumas

Topics

This worksheet focuses on subclasses and inheritance. Part of it involves extending the robot simulation from lectures 5 and 6.

Resources

These things might be helpful while working on the problems. Remember that for worksheets, we don't strictly limit what resources you can consult, so these are only suggestions.

1. Get the Project 1 starter pack

Project 1 is due on 10 February. To prepare for working on it, please download and extract ths starter pack, which is a ZIP file:

You don't just want to view the contents of the ZIP file in Windows explorer; it's important to actually extract the files so they exist in a directory where you can do your project work.

When you've extracted the starter pack, check that you know the location of simulation.py and that you can run it in the terminal.

The point of asking you to do it during lab is to ensure the TA can help you if you run into any problems.

2. Additional bots

Download these files related to the robot simulation from the course sample code repository and put them in a directory where you'll do your work for this problem.

Then, build these new robots in bots.py that are subclasses of Bot:

  • class DelayMarchBot

    • A robot that waits for a specified number of time units, and thereafter marches in a direction (default is Vector(1,0), but any direction can be specified in an optional constructor argument)
  • class ParallelogramPatrolBot

    • The constructor takes two vectors v1 and v2 and two integers n1 and n2.
    • The robot marches in a parallelogram (as shown below) by
      • Taking n1 steps in direction v1, then
      • Taking n2 steps in direction v2, then
      • Taking n1 steps in direction -v1, then
      • Taking n2 steps in direction -v2, then
      • Repeating this cycle

  • class RandomItinerantBot
    • At any given time, this robot can be in either of two "modes": walking or waiting
    • When waiting, at each time step there is a 5% chance it decides to switch to walking mode, and a 95% chance it stays in waiting mode. (Use the random module to decide.)
    • When switching to walking mode, the robot chooses two parameters:
      • A direction, which is a Vector2 randomly selected from a list of four vectors representing up, down, left, and right.
      • A length, which is the number of steps it will take in this direction
    • When in walking mode, the robot takes another step in the chosen direction. If it has completed length steps, then it switches back to waiting mode.
    • Finally, this class has a new method startle() that, when called, will make it so that the robot switches to walking mode the next time update() is called.
    • Overall, the route of this robot might look like the one shown below (but will be different each time the simulation is run).

Add these robots to the simulation and confirm they exhibit the expected behavior. Use class attributes to give the new robot classes their own symbols.

3. UnitVector2

In plane.py add a subclass UnitVector2 of Vector2 that represents a unit vector (a vector of length 1) in a specified direction. The constructor should accept a single float theta instead of the two coordinates x and y that are expected by the Vector2 constructor. The constructor should then initialize the object so that the x coordinate is cos(theta) and the y coordinate is sin(theta). All three quantities (theta, x, y) should be stored as instance attributes.

The functions sin and cos are found in the math module.

Also, recall that Vector2 objects support addition and scalar multiplication. But the sum of two unit vectors is usually not a unit vector, nor is a scalar multiple of a unit vector. Is this going to cause problems? If you add two UnitVector2 instances, do you get a UnitVector2 or Vector2?

Bonus round

Work on these open-ended problems if you finish the exercises above. We don't plan to include solutions to these in the worksheet solutions.

ParametricWanderBot

Make a robot class that behaves like WanderBot or FastWanderBot, but which allows any list of possible direction vectors to be given as an argument to the constructor. The robot then chooses a random element of the provided list of vectors for each step.

NotifyDestructBot

Make a robot class (a subclass of DestructBot) that stands still for a specified number of steps and then deactivates. But before it does so, this class calls a user-specified function. The function is given as an argument to the constructor. So, for example:

def bye():
    """Robot says goodbye"""
    print("Thanks for including me in this simulation.  My battery is running low so if it's OK with you I'll just power down now. Bye.")

R = bots.NotifyDestructBot(position=Point(3,3),active_time=10,action=bye)

# ... code to run the simulation ...

should make a robot that sits at position (3,3) for 10 steps, prints a message, and then deactivates.

The action argument of the constructor should default to None, and the class should know to not do anything if action==None. That way, any code that works with DestructBot will also work with NotifyDestructBot.