Program Setup

In addition to the files you already used in the Warmup, your repository contains several starting files: constants.py, critter_gui.py, critter_sim.py, critter_run.py, and critter.py. These files implement a graphical simulation of a 2D grid world with many different critters moving around in it. Different kinds of critters move in different ways; as you write each class, you are defining those differences.

ReadMe

You should not modify any of the code in constants.py, critter_gui.py, critter_sim.py, critter_run.py, and critter.py. Whenever you want to define a new critter, you should create a new file associated with the critter’s name (e.g., implement the Tiger class by making a file called tiger.py).

Every critter you implement will either be a subclass of the provided Critter class (found in the critter.py file) or of another critter. This means that your implementations must adhere to the specific interface (i.e., some specific state and functionality) of the superclass.

For each new critter you define, the majority of the work will be to overload methods defined in the Critter superclass for which the new critter wants different (i.e., not default) behavior. Some of the methods you’ll be asked to overload include get_color(), get_char(), get_move(), fight(), and recover(). As an example, below is a definition for a class called Sloth that is part of the simulation. Sloth critters are displayed in the world with the letter S, are brown in color, always stay in their current location (i.e., they return constants.CENTER for every move), and always choose to constants.ROAR in a battle—sloths are ferocious animals.

import critter
import constants

class Sloth(critter.Critter):
  """Defines a Sloth."""
  
  def get_color(self):
    return constants.BROWN

  def get_char(self):
    return 'S'

  def get_move(self, self_info):
    return constants.CENTER

  def fight(self, opp_info):
    return constants.ROAR

You already have this code in a file called sloth.py. When you run critter_run.py you should see some sloths in your world. Of course, sloths don’t move, so even when you press the Go button, nothing happens!

There are two important things to note about the implementation of Sloth above. First, the Sloth class does not override all of the methods from the Critter class. Instead, it only overrides the methods needed to define its behavior. Second, Sloth makes use of values defined as constants from the constants module. These are values that are used by the critter simulation—it’s important that you use them consistently to reference the following categories throughout your code:

  1. Colors - there are nine colors defined in constants.py (e.g., constants.GRAY, constants.ORANGE)
  2. Directions - there are constants for the four cardinal directions (constants.NORTH, constants.EAST, constants.SOUTH, constants.WEST), the four diagonal directions (constants.NORTHWEST, constants.NORTHEAST, constants.SOUTHEAST, constants.SOUTHWEST), and the “remain” direction (constants.CENTER)
  3. Attacks - there are three possible attacks: constants.ROAR, constants.POUNCE, and constants.SCRATCH

Your code should not depend upon the specific values assigned to these constants, although you may assume they will always be of type int.

What’s Next!

In the following parts of the lab, you’ll be asked to implement 6 different critter classes. Each class must have only one constructor and that constructor must accept exactly the parameter(s) described in the accompanying table. For random moves, each possible choice must be equally likely (with the exception of your DIY critters). In total, your final simulation will have the following critters: Sloth, Mouse, Tiger, Elephant, OppositeElephant, Chameleon, and your DIY critter.

Take some time to properly design your classes. Use static (non-instance) variables and the given constants where appropriate.