Sponsored by the Mathematics and Computer Science Department and the Academic Council.

Critters Tournament - Survivor Edition

Submissions due Monday (12/9/2013) at 11:59pm


RULE CHANGES! Survivor Edition - You must have at least one of your critters alive to win. Once you have zero critters, your score drops to zero. Similar to last year, each of your critters and each of your kills are now worth 3 points. Food is only worth 1 point. Be sure to download the new version of CritterMain.java if you have competed before.

This project enables you to test your game playing strategy by designing a Critter for head-to-head combat in a tournament. Although the rules are fairly simple - the strategy can be highly complex. Although some basic coding skills in Java are required, the real challenge here is in your strategy.

Students in the CS106 class this term will be using this as an assignment (please excuse the "homework" tone) and they will compete within their own bracket. Students not currently enrolled in CS106 will compete in a separate bracket. Winners of each bracket will receive awards and will then compete head-to-head for posterity.

Thank you to the developers of Critters. Critters was developed at the University of Washington by Stuart Reges and Marty Stepp.

Program Behavior:

You will be provided with several classes that implement a graphical simulation of a 2D world with many animals moving around in it. You will write a set of classes that define the behavior of those animals. Different kinds of animals move and behave in different ways. As you write each class, you are defining those unique behaviors for each animal. The critter world is divided into cells with integer coordinates. The world is 60 cells wide and 50 cells tall. The upper-left cell has coordinates (0, 0); x increases to the right and y increases downward.


On each round of the simulation, the simulator asks each critter object which direction it wants to move. Each round a critter can move one square north,southeastwest, or stay at its current location. The world has a finite size, but it wraps around in all four directions (for example, moving east from the right edge brings you back to the left edge). You might want your critters to make several moves at once using a loop, but you can't. The only way a critter moves is to wait for the simulator to ask it for a single move and return that move.


As the simulation runs, animals may collide by moving onto the same location. When two animals collide, if they are from different species, they fight. The winning animal survives and the losing animal is removed from the game. Each animal chooses one of Attack.ROARAttack.POUNCE, or Attack.SCRATCH. Each attack is strong against one other attack (e.g. roar beats scratch) and weak against another (roar loses to pounce). The following table summarizes the choices and which animal will win in each case. To remember which beats which, notice that the starting letters of "Roar, Pounce, Scratch" match those of "Rock, Paper, Scissors." If the animals make the same choice, the winner is chosen at random.

Critter #2


Attack.ROARrandom winner#2 wins#1 wins
Critter #1Attack.POUNCE#1 winsrandom winner#2 wins

Attack.SCRATCH#2 wins#1 winsrandom winner
If two animals of the same species collide, they "mate" to produce a baby. Animals are vulnerable to attack while mating: any other animal that collides with them will defeat them. An animal can mate only once during its lifetime.


The simulation world also contains food (represented by the period character, ".") for the animals to eat. There are pieces of food on the world initially, and new food slowly grows into the world over time. As an animal moves, it may encounter food, in which case the simulator will ask your animal whether it wants to eat it. Different kinds of animals have different eating behavior; some always eat, and others only eat under certain conditions. Every time one class of animals eats a few pieces of food, that animal will be put to "sleep" by the simulator for a small amount of time. While asleep, animals cannot move, and if they enter a fight with another animal, they will always lose.


The simulator keeps a score for each class of animal, shown on the right side of the screen. A class's score is based on how many animals of that class are alive, how much food they have eaten, and how many other animals they have killed.

Provided Files:

Each class you'll write will extend a superclass named Critter. This is an example of inheritance, as discussed in the textbook. Inheritance makes it easier for our code to talk to your critter classes, and it helps us be sure that all your animal classes will implement all the methods we need. But to do this assignment you don't need to understand much about inheritance. Your class headers should indicate the inheritance by writing extends Critter, like the following: 

public class Bear extends Critter { ...

The Critter class contains the following methods, which you need to write in each of your classes:

Just by writing extends Critter as shown above, you receive a default version of these methods. The default behavior is to never eat, to always forfeit in a fight, to use the color black, to always stand still (a move ofDirection.CENTER), and a toString of "?". If you don't want this default, rewrite (override) the methods in your class with your own behavior. For example, below is a critter class StoneStones are displayed with the letter"S"gray in color, never move, never eat, and always roar in a fight. Your classes will look like this class, except with fields, a constructor, and more sophisticated code. Note that the Stone does not need an eat() or getMove()method; it uses the default behavior for those operations.

import java.awt.*;
// for Color
public class Stone extends Critter {
 public Attack fight(String opponent) {
 return Attack.ROAR;

 public Color getColor() {
 return Color.GRAY;

 public String toString() {
 return "S";

Running the Simulator:

When you press the Go button on the simulator, it begins a series of turns. On each turn, the simulator repeats the following steps for each animal in the game:

After moving all animals, the simulator redraws the screen, asking each animal for its toString and getColor values.
It can be difficult to test and debug this program with so many animals on such a large screen. We suggest using a smaller game world and fewer animals (perhaps just 1 or 2 of each species) by adjusting the game's initial settings when you run it. There is also a Debug checkbox that, when checked, prints a large amount of console output about the game behavior.

The code for the simulator is provided below.

This project requires skills with inheritance and polymorphism. In the world will be Critters of three types (Bear, Lion, Tiger). To run and test your Critter you want to write the following classes (you will submit only your own Thoroughbred Class):

  1. Bear -- Bears are always hungry, scratch when fighting, and either move north or west.
  2. Lion -- Lions get hungry after they fight, they either roar or pounce, and they move in circles.
  3. Tiger -- Tigers have a fixed amount of food they can eat, either scratch or pounce, and move randomly.
  4. Thoroughbred -- Each Thoroughbred is unique, you will decide the behavior of your own Thoroughbred!

Custom Critters:

Below are the descriptions of the Critters that you will want to write to test out your Thoroughbred Critter.


The Bear constructor accepts a parameter representing the type of bear it is: true means a grizzly bear, and false means a polar bear. Your Bear object should remember this and use it later whenever getColor is called on the Bear. If the bear is a grizzly, return a brown color (a new Color(190, 110, 50)), and otherwise a white color (Color.WHITE).


Think of the Lion as having a "hunger" that is triggered by fighting. Initially the Lion is not hungry (so eat returns false). But if the Lion gets into a fight or a series of fights (if fight is called on it one or more times), it becomes hungry. When a Lion is hungry, the next call to eat should return true. Eating once causes the Lion to become "full" again so that future calls to eat will return false, until the Lion's next fight or series of fights.


The Tiger constructor accepts a parameter for the maximum number of food this Tiger will eat in its lifetime (the number of times it will return true from a call to eat). For example, a Tiger constructed with a parameter value of 8 will return true the first 8 times eat is called and false after that. Assume that the value passed for hunger is non-negative.

The toString method for a Tiger should return its remaining hunger, the number of times that a call to eat would return true for that Tiger. For example, if a new Tiger(5) is constructed, initially that Tiger's toStringmethod should return "5". After eat has been called on that Tiger once, calls to toString should return "4", and so on, until the Tiger is no longer hungry, after which all calls to toString should return "0". Recall that you can convert a number to a string by concatenating it with an empty string. For example, "" + 7 evaluates to "7".


You will decide the behavior of your Thoroughbred class. Pahe following are some guidelines and hints about how to write an interesting Thoroughbred. There are additional methods that each critter can use through inheritance from the Critter class. Your Thoroughbred may want to use these methods to guide its behavior. None of the methods below are needed for BearLion, or Tiger.

Your Thoroughbred's fighting behavior may want to utilize the parameter to the fight method, opponent, which tells you what kind of critter you are fighting against (such as "B" if you are fighting against a Bear).

Your Thoroughbred can return any text you like from toString (besides null) and any color from getColor. Each critter's getColor and toString are called on each simulation round, so you can have a Thoroughbred that displays differently over time. The toString text is also passed to other animals when they fight your Thoroughbred; you may want to try to fool other animals.

On the evening of Thursday, the last week of class, we will host a Critter tournament. In each battle, two students' Thoroughbred classes will be placed into the simulator along with the other standard animals, with 25 of each type. The simulator will run until no significant activity occurs or 1000 moves have passed. The student whose Thoroughbred has the higher score in the right sidebar advances.

Supplemental Files

In order to complete your assignment, you will need the code for the base class CritterYOU MUST HAVE THIS FILE IN ORDER TO COMPILE YOUR CRITTERS. The source code for this class is here: Critter.java. You should save this code in a file named Critter.java, and put it in the same folder as the other classes you write for this assignment. YOU SHOULD NOT EDIT THECritter.java FILE IN ANY WAY!!

Additionally, you can test your critters in the Critter colliseum using theCritterMain class, which is provided here: CritterMain.java. You should save this code into a file named CritterMain.java, and put it in the same folder as Critter.java and the other classes you write for this assignment.YOU SHOULD NOT EDIT THE CritterMain.java FILE IN ANY WAY!!!

YOU DO NOT NEED TO EDIT OR TURNIN Critter.java OR CritterMain.java.

Generating random numbers

In this assignment, at least for the Tiger class, you will need to generate random numbers. The easiest way to do this is to use the classjava.util.Random. The Random class has a default constructor, which will create a new Random object that is ready to give you random numbers. The method you will most likely want to use is Random.nextInt(int n), which will return a random integer in the range 0 to (n-1).

So, for instance, in your Tiger class you are supposed to choose random directions. Since there are 4 of them, you can make a call to nextInt(4), which will return either 0,1,2, or 3. You can associate each of these with the directions NORTH, SOUTH, EAST, and WEST in whatever way you like.


You can test your Critters by running them in the Critter colliseum. To do this, simply download the CritterMain class and run it from the command line.

When you run CritterMain, it will scan the current folder and look for any class files that extend the Critter class. Then it will ask you which of those classes you would like to load into the colliseum. The best way to test your individual critters is to load them one at a time into the colliseum and see if they exhibit the correct behavior.

Critters Tournament Submission

Please e-mail your Critter to Dr. Porter (Leo.Porter(at)skidmore.edu). Name the e-mail "Critters Tournament".  Name the file you send "<CritterName>.java" where <CritterName> is the name of your critter. Also, let me know the last names of you and your partner or just your last name if submitting individually.

Let the tournament begin.