PreLab 09

Critter Tournament
Due in class on Wednesday, April 8

This week you will write a set of classes that define the behaviour of various animals in a 2-dimensional grid world. Your animals will roam the world, and, should they happen upon another animal, will fight to the death. We will first describe some particular animals we want you to create, and then ask you to come up with an animal (or more) of your choosing. Please write or type up your solutions, and hand in a paper copy before the beginning of class on Tuesday. Remember, no late prelabs allowed!

Part 1 - Program Summary

Before you start, let's take a look at this screenshot of the animal world, which is shown below.

What you see here is a grid with mice (labeled 'M'), stones (labeled 'S'), hippos (labeled 'H'), lions (labeled 'L'), and chameleturtles (labeled 'T'). This is their initial placement in the grid world. The Go button starts the simulation; on each round of the simulation, each critter (stones count as critters here, albeit relatively uninteresting ones) is asked which direction it wants to move. On each round, each critter can move one square to the north, south, east, west, or stay at its current location. Critters move around in a world of finite size, but the world is toroidal, as it was in our game of life (going off the end to the right brings you back to the left and vice versa; going off the end to the top brings you back to the bottom and vice versa).

At the beginning of the simulation, each critter is asked to supply an attack and a defense value that it will use for the entire game via its getStats method; these values cannot be changed once they are set. As the simulation runs, animals may collide by moving onto the same location. When two animals collide, they fight using their attack and defense values. If the attacking critter is successful in killing its opponent, the loser is removed from the simulation and the attacker is allowed to move into their spot. Otherwise, both critters remain in the simulation where they were before.

Each critter starts off with 50 health points. Their attack and defense values can be anywhere between 0 and 100, but the sum of both cannot be greater than 100. When two critters fight, the moving critter is registered as the attacking critter and the other is the defender. The defense of the defender is subtracted from the attack of the attacker, and if the result is positive, it is then subtracted from the health of the defending critter. If the defending critter's health reaches or goes below 0, they are are killed. If not, they survive the attack. A 2x bonus is awarded to the defense of a critter whose last move was to stay still. For the first round, every critter that has not yet moved receives this bonus.

Attacker
100 Attack 50 Attack 0 Attack
Defender 100 Defense  0 Damage  0 Damage 0 Damage
50 Defense 50 Damage  0 Damage  0 Damage
  0 Defense   100 Damage 50 Damage  0 Damage 

Critter Behaviour

Each critter you implement must have some specific state and functionality defined. In particular, each critter will implement the following methods, amongst other things:


    def getColor(self):
    def getMove(self, info):
    def getStats(self):
    def getChar(self):

For example, a Stone may be implemented with the following functionality, where C and GRAY are defined critter constants:


import critter
import color    

class Stone(critter.Critter):

    def getStats(self):
        return 0, 100
    
    def getColor(self):
        return color.GRAY    # Stones are drawn GRAY
    
    def getMove(self, info):
        return critter.C  # Stones never move

    def getChar(self):
        return 'S'  # Displayed with an 'S'

Critters To Implement

In your lab you will be implementing the following five critters, which must have the following behaviour:

Mouse

 stats  Attack: 60, Defense: 40
 movement behaviour  alternates between EAST and SOUTH in a zigzag pattern (first EAST, then SOUTH, then EAST, then SOUTH,...)
 character  'M'

Hippo

 stats  attack: 40, defense: 60
 color  color.BLUE
 movement  first go SOUTH steps times, then go WEST steps times, then go NORTH steps times, then go EAST steps times, then stay still steps times (a clockwise square pattern), then repeats
 character  'H'

Lion

 stats  attack: 100, defense: 0
 color  alternates between color.ORANGE and color.BLACK (first color.ORANGE, then color.BLACK, then ...)
 movement  looks NORTH, then EAST, then SOUTH, then WEST. If at any point it sees a critter that doesn't display as 'S', 'T', or a number, it attacks. Otherwise, returns a random direction.
 character  'L'

The Chameleoturtle

 stats attack: 50, defense: 50
 color the color of the last critter to attack it; if it hasn't been attacked yet, color.GREEN
 movement  if any critters it can see anywhere within its sights aren't other Chameleoturtles, Stones, or Point Caches, stays still. Otherwise, moves NORTH
 character the character of the last critter to attack it; if it hasn't been attacked yet, 'T'

Your Own Critter

 stats  you decide
 movement behaviour  you decide
 character  you decide

You will decide the behaviour of your own critter. Your critter should be named after yourself. Please use your first name followed by your last initial. For example, my critter would be named BobG.

What Should Your Critter Do?

Part of your lab grade will be based upon writing creative and non-trivial behaviour for your own critter. The following are some guidelines and hints about how to write an interesting critter.

When a critter moves, it has access to some important but limited information that it may wish to use to guide its movement behaviour. For example, it has access to its current x and y coordinates, as well as the width and height of the grid world. It can also find out what kind of critters are to its east, west, north, south, north-east, north-west, south-east, or south-west if there are any critter there at all. Note that you can see diagonally, but you cannot move diagonally (in one step).

1) A non-confrontational (or introverted) critter may always want to move away from other critters. If such a critter sees another critter to the north it shouldn't move north, but additionally, south is probably safer than either east or west. Unless of course there is another critter to the southwest, in which case maybe east is the best bet.

One could imagine (unpleasantly) making a couple hundred if-statements to handle every possible configuration of neighbors. But we'd like to be a bit smarter (and more concise). One idea is this: make a variable for each of the four cardinal directions representing the "danger score" of moving in that direction, plus a danger score for not moving at all. For each neighbor you see, increase the danger scores in a way that represents the threat posed by that neighbor. Then pick the direction with the lowest danger score.

Give pseudocode that determines where such a critter should move based on its neighbours to the north, south, east, west, north-east, north-west, south-east, and south-west. In generating danger scores, the precise numbers you choose are up to you, but try to make sure they make lead to reasonable choices in various situations.

2) What if the critter only wants to avoid critters of a different type than itself? How would you change your pseudocode from question 1?

3) If you are fighting a Mouse, what stats should you have in order to always win if the mouse is attacking? What if you are attacking the mouse? How about against an Hippo?

Your critter can use any character you like as its display character. In fact, critters are asked what display character to use on each round of the simulation, so you can have a critter that displays itself differently over time.

Although your stats cannot be changed once they are set in the beginning, not all of your critters have to be identical. Some clever manipulation of class variables and a decent game plan will put you far ahead of other, less-sophisticated critters.


Here are some things to think about, but not to hand in:

Find a way to distribute the stats for your critters, so that not every critter of your type has the same set of stats.

Describe one way that critters of your type could coordinate - use class variables to have them work together.

Describe the behavior of your own critter by filling out the "you decide" entries in the Your Own Critter table further up in this prelab. Try to make it interesting without getting overly ambitious (there is only so much information available to you). Don't specify actions that go beyond the scope of what a critter is allowed to do -- long-range attacks, teleportation, and invulnerability are all no-nos.


Honor Code

If you followed the Honor Code in this assignment, write the following sentence attesting to the fact at the top of your homework.

I affirm that I have adhered to the Honor Code in this assignment.