PSA 5: Inheritance and Critter Simulation
In this programming and problem-solving assignment, you will write several lineages of Critters and test your gameplay strategy by designing your own Critter for a head-to-head combat in a tournament. The rules are generally simple, but there are some nuances to the rules. Your strategies can be highly complex. You will learn both a new object-oriented design paradigm using inheritance as well as entering challenges against both our provided and your classmates Critters.
The code you will write will have effects that can be seen mostly visually. Therefore, the action of testing out your programs will be running the simulation and observing the behaviors. In addition to writing five classes to our specifications, you will implement one more Critter . You will iteratively improve its strengths in order to beat the four aptly named Critters and a Mystery Critter. The implementation of Mystery will be hidden from you. Finally, your Critter can be entered into a several-thousand Critter competition with your classmates to see whose Critter will come out the strongest and luckiest. The top 30 winners of the competition will receive a 3D printed sculpture of an animal. The developers who rank top ten will receive special Critters! Below is a subset of the critters you could win:
For this assignment, there is no special need to think of edge cases as the program is already written for you. The program IS the simulation! If your Critter works for the program on your computer, it will work for ours.
Thank you, to the developers of Critters. The original version of Critters was developed at the University of Washington by Stuart Reges and Marty Stepp.
Follow the code of academic integrity. May everyone enjoy this assignment and compete in a fair game.
Link to starter codes: here
1
Helpful Information:
- Online Communication: Using Piazza, Opening Regrade Requests
- Getting Help from Tutor, TA, and Professors Hours
Lab and Office Hours (Always refer to this calendar before posting.)
- Academic Integrity: What You Can and Cant Do in CSE 8B
- Setting Up the PSA
- How to Use Vim
- Style Guidelines
- Submitting on Vocareum and Grading Guidelines
Table of Contents:
The Arena
The Assignment
Part 1: Getting to Know the Critter Family [15 Points]
Part 2: Completing the Critter Family [45 Points]
Part 3: Inheritance Concepts [10 Points]
Part 4: Your Critter [20 Points]
Part 4.1: Your Critter, with Thousands of Others
Part 5: Command Questions and Program Descriptions [10 Points] Part 6: Dragon [+10 EC Points]
Submission and Grading
2
The Arena
Several classes in the starter code implement a graphical simulation of a 2D world with many animal moving around in it. You will write a set of classes that define the behavior of these animals. As you write each class, you are defining the unique behaviors for each animal. You will also notice that there may be similarities between animals of closer family relations, such as the Turtle and GreenTurtle. The Critter World is divided into cells with integer coordinates. The world is 60 cells wide and 50 cells tall by default. The upper-left cell has coordinates (0, 0). The x coordinate increases to the right. The y coordinate increases downwards.
Movement
On each round of the simulation, the simulator asks each Critter object which direction it wants to move by calling its getMove method. Each round a Critter can move one square north, south, east, west, OR stay at its current location (i.e. center). 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). It might be tempting to allow your critters to make several moves at once using a loop, but you cant. The only way a critter moves is to wait for the simulator to ask it for a single move and return that move.
Fighting
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.ROAR, Attack.POUNCE, or Attack.SCRATCH as their attack mode. Each attack is 96% strong against one other attack (e.g. roar beats scratch) and weak against another (roar loses to pounce). This means that scratch will beat roar
3
4% of the time. In addition to considering the attacks of each animal, you need to account for the 4% off-chance that the attack will backfire. It is not a large amount, but just remember its existence.
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 complete random.
The relationship of different attack actions are listed in the following table. Keep in mind that there is 96% chance involved if there is a clear winner. We didnt put this information in the table.
Critter #2
ROAR
POUNCE
SCRATCH
ROAR
random (50% chance)
#2
#1
POUNCE
#1
random (50% chance)
#2
SCRATCH
#2
#1
random (50% chance)
Critter #1
Mating
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 baby will be a full adult by birth and will spawn next to the parent critters when they finish mating.
Eating
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. Once an animal has eaten a few pieces of food, that animal will be put to sleep by the simulator for a small amount of time. During the sleeping period the animal will automatically forfeit all fights, meaning it will lose to all other critters that attack it.
Scoring
The simulator keeps a score for each class of animal, shown on the right side of the screen. A classs 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 defeated.
4
The Assignment
Each class you write in this section will inherit from a superclass, and may be inherited by a subclass. We take advantage of inheritance in two ways: since subclasses automatically inherit methods from their superclass, if we want a certain method to be uniform across a family of classes, we can simply define the method in the superclass. All related subclasses will inherit that method. If we want to change that behavior for all, then we only need to change the method that was defined once. Define for one, define for all. The other way we take advantage of inheritance is that we do not have to type as much code. This reduces the possibility of error. Inheritance provides the programmer assistance in streamlining the code writing process. Define for one, define for all.
You are provided with a UML diagram of the Critter family tree in Part 1 of the assignment. In this diagram, we tell you in addition to what bloodline that the Critters have, which classes are provided, which classes you do not need to edit, and which classes require you to write the file from scratch.
First, look at the Critter.java class. It contains helpful documentation from various previous writers of the Critter class and may prove very useful to knowing what each method does, which ones are provided, and which ones you might be working on. This class is an abstract class.
Just by defining a class to extends Critter, you receive a default version of the methods defined in Critters.java. Look inside the file to see what the default behaviors are for each of the following methods: eat, fight, getColor, getMove, and toString. If you dont want this default behavior, you will then override the inherited methods in your class through your own definition of the method. The method will have the exact same signature and return type, but your own implementation will be used over the inherited one. Here is an example of a class that inherits from Critter.
import java.awt.*;public class Stone extends Critter {
@Override /* You MUST use @Override for every method you override. We require it because it introduces you to using annotations and ensures that you will correctly override methods! */
public Attack fight (String opponent) { return Attack.ROAR;
}
@Override public Color getColor () {
return Color.GRAY;
}
@Override public String toString() {
} }
return S;//This double quote may not compile correctly if you copy it into Java.
5
Running the Simulator
The steps to getting the simulator running are slightly longer than 2048s steps. First, compile all necessary classes. You can compile separately if needed, but javac *.java is most convenient. A large number of new class files will show up in your folder and you may see uses or overrides a deprecated API but dont worry about them. Next, run the simulator with java CritterMain. You will see the following screen. You can enable Debug output which will print debug messages to your terminal. You can enable various Critters.
You may see some warnings of deprecated APIs when you run the simulator. You can ignore these warnings.
You have many options in the next screen. You can adjust the speed of the simulator. When you press Go, the simulation will take off and run. You can Stop the simulation. For visual testing, you can click Tick, which will run one round of the simulation. If you would like to see debug messages on your terminal as your simulation runs, enable Debug.
Accounting for Randomness
As you begin to implement your code, you will notice that there is a large presence of randomness involved. To match our code, each Critter that will use randomness will have its constructor initialize its random variable. With random related code, you can only use the following two methods:
- Randoms one-argument constructor: Random(long seed)
- Randoms nextInt method: nextInt( int bound )
6
Part 1: Getting to Know the Critter Family [15 Points]
This portion introduces you to writing classes with inheritance. If you have not read the Critter.java file, do so now. Critter is the abstract class from which all subclasses will be derived, directly or indirectly. This file will also contain enums that are important for you to use in the following tasks. There are five classes in total you will work on, hence there will be five classes you will write with style. See the UML diagram on the next page for a graph of the family. Note that Critter is an abstract class though it doesnt have any abstract method. We didnt list instance variables in the UML. The general rule is you should appropriately define instance variables that the specification requires. You can have additional instance variables if needed for all the class that you implement.
7
Inheriting from Critter
Next, take a look at HappyAnimal.java, which is a provided class that you do not need to edit. Its functions are incomplete though. So what would happen if you instantiated HappyAnimals on the simulation? Try it now by compiling and run the simulation on HappyAnimal. You dont have to modify the HappyAnimals class for this PSA.
By writing a HappyAnimal class, we can define a subset of Critters that are happy. The subclasses of HappyAnimal will inherit its characteristics, and you will have the choice of overriding any of those characteristics.
8
Your turn. You will implement a class that is parallel to the HappyAnimal: the SadAnimal class (SadAnimal.java in the starter code). SadAnimal is a partially implemented Critter whose behavior can be seen in the simulation as incomplete. Notice that there is already a provided class that extends SadAnimal the Omnivore. The methods you write in SadAnimal will not only be affecting SadAnimal.java, but also all subclasses that choose to extends SadAnimal but chooses to not override the methods. Because of this, writing code for SadAnimal is very important to get right. The definition will affect many other classes!
SadAnimal class
- Instance variables: The SadAnimal knows the following things: a String that it will use to identify itself, a Color it will display itself with, a boolean to know whether it has eaten yet, a Random object when it needs to be able to make arbitrary decisions or some other purpose, and an int by which the SadAnimal or its descendants will count. All these fields should be protected. Again, you should define these variables appropriately, and you can have more instance variables if you think they are necessary.
- No-arg constructor: Instantiate all instance variables except the Random and count variables. You will notice that SadAnimal in particular did not have a use for Random or count but its subclasses might. The boolean indicator variable should be initialized as false, the color should be red, and the name of the SadAnimal is the three character String: :-(.
- Override getMove method: SadAnimal has the ability to move but it is only able to alternate between moving south, or west. By default, it will always move west first, and then when it eats, it changes direction to south. When it eats again, it will go west, and the pattern continues. If the World runs out of food, its stuck going in one direction!
- Override eat method: When presented with food, SadAnimal will always eat.
- Override getColor method: Return the color field. Dont return red directly as a hard-coded
color. Make sure you return the field.
- Override toString method: Return the string field. Similarly like the getColor method, dont
return the hardcoded name. Return the correct field.
Inheriting from Classes that Inherited from Critter
Now that you have finished implementing SadAnimal, we will move one level lower. The Sloth is a fully implemented animal! Be careful though, that does not mean that Sloth overrides all the methods it inherited from HappyAnimal; it means simply that all the functions will have some kind of implementation, simple or hard, and inherited or overridden. Also, remember that the Sloth inherits instance variables from its superclasses too.
Sloth class
- Instance Variables: Specific to the Sloth, it is very important to remember whether it has eaten previously, and whether it moved north. You should design how many instance variables you need and their types. The goal is to make sure your methods work correctly with the help from these instance variables. All instance variables should be protected.
- Constructor: Notice that Sloth inherited the random reference variable from HappyAnimal. Sloth will instantiate a new Random with the seed 2048, and assign this new instance to that inherited reference variable. Upon birth, Sloths are named S, know that they have not yet eaten previously, and intuitively decide to move north first.
9
Override eat method: Sloth loves to eat. When encountering food, the Sloth will have only 95% chance of eating that food. If the Sloth did choose to eat the food, the next time the Sloth encounters food, it will have a 96% chance of eating it. Otherwise, it will just remain 95%. If the Sloth had a 96% chance of eating, but did not eat, then it will return back down to 95%. If it does eat, it remains at 96%.
Override fight method: 10% chance of roar and 90% chance of scratch.
Override getMove method: The Sloth will alternate in moving north and east, starting with north when it is first born.
Override sleep and wakeup methods: Sloths identity is an S whenever it wakes up, but whenever it sleeps, it will appear to other Critters as Zzz.
Now,
not a
do not necessarily need to have the same rate of implementation completeness going down the inheritance family. We fully implemented Sloth extending from HappyAnimal because we could. But we can also implement a slightly complete, but not fully complete, animal from SadAnimal, because we can.
lets look at the Omnivore, which extends from SadAnimal that you implemented. Notice that this is particular animal! Although the Sloth is a fully implemented animal inherited from HappyAnimal, we
Part 2: Completing the Critter Family [45 Points]
This part continues directly from Part 1. In this section, you will define Critter classes from scratch, and then override certain methods inherited from Critter, SadAnimal, and Omnivore. In addition, there will be certain new methods that will be implemented as part of the three classes you will implement. There will be two lineages that inherit from the Omnivore: Turtle and GreenTurtle, and Leopard.
Lets implement the Leopard first. The Leopard is the last subclass in its lineage, which goes Critter SadAnimal Onnivore Leopard. The Leopard inherits from Omnivore, which is a provided file, but has inherited some fields from SadAnimal which you implemented. So, while some fields inherited from Omnivore were inherited directly, others were inherited from SadAnimals. The Leopard has one unique instance variable that needs to be implemented, which results in a more unique behavior for eat and fight.
Leopard Class
- Instance variables: Each Leopard, in addition to the instance variables inherited from its superclasses, will all telepathically keep track of their confidence together. The confidence starts at 10 when the simulation starts. When the confidence of one Leopard is affected, All Leopards confidence will be affected in the exact same way. (Hint: What type of modifier can you apply to a variable to make that variable shared across all instances?)
- No-arg constructor: Initialize the variable count (inherited from SadAnimal). The value you use is up to you though it will be wise to see how you might need to use count in the getMove method. Leopards random will initialize with a seed of 2017. Additionally, the Leopards self-identity as Li and are orange.
- Override win and lose method: If a Leopard wins a fight, all Leopards confidence will increment if their confidence is less than 10. If a Leopard loses, all Leopards will reduce their confidence by 1 if their confidence is greater than zero. The minimum confidence they have is 0, and the maximum is 10. (Think: where do these two methods come from?)
10
- Override getMove method: The Leopard will move south five times, west five times, north five times, and eas five times, prowling around this square motion for the remainder of its life. Leopard remembers this by using its inherited memory to incrementally count.
- Override eat method: The Leopards will always have (confidence * 10)% chance of eating. If confidence is at 2, then there is a 20% chance of eating.
- Override fight method: When fighting, if the opponent is the Omnivore class (NOT a subclass of Omnivore) OR when all Leopards have a confidence HIGHER than 5, then the Leopard will scratch. Else if all the Leopards have a confidence less than 2, they are too scared to attack and forfeit. Otherwise the Leopard will roar.
The Turtle starts a lineage that diverges from Leopard. The Turtle extends from Omnivore and is in general slow and indecisive. The Turtle often likes to think about what attack it will use, and so it makes a decision not only when it is about to fight, but also after a fight and when it encounters food. Turtles are able to walk in one directly only, and gets tired easily so it always waits two times before moving again. The Turtle is thoughtful, but slow and indecisive.
Turtle Class
- Instance Variables: an Attack type reference and any other instance variables you may need.
- No-arg constructor: Self-identifies as Tu and is color cyan. Initialize count to the value you
choose, and the random will instantiate with a seed of 8.
- New method to decide attack generateAttack(): Turtle will often think about what attack it
wants to use next, and this method sets the attack mode of turtle (i.e. change the attack field of Turtle). This method will randomly set with equal chance between all three non-forfeiting attacks. The Turtle will decide its attack mode in three different scenarios (i.e. call this generateAttack method): (1) when it wins a fight, (2) when it eats, and (3) right before it fights. The thought process is the same in all of these actions. Be careful with this description, as it affects more than one method.
- Override getMove method: Turtle will stand still two times, and then move north, repeating this pattern for the duration of the simulation. You can use the inherited count variable to keep track of the pattern.
- Override fight method: The Turtle will decide what attack to use one more time right before the fight. Then return the attack field.
- Override win method: Upon winning a fight, Turtle decides a new attack.
- Override eat method: The Turtle will never eat, but upon encountering food, the Turtle decides a
new attack.
Next, the GreenTurtle, which should extends from Turtle. GreenTurtle is even more thoughtful than Turtle. It not only thinks about what attack is should do next, but also which direction to move. GreenTurtle always moves in some direction, and is decisive on what attack it should do. GreenTurtle goes through various thoughts upon doing various actions as described below. In short, although GreenTurtle is indecisive about which direction to move, it is decisive on its attack, fast, and versatile.
GreenTurtle Class
Instance Variables: should remember the next intended Direction to take. You can design any other fields that deem appropriate. (Think: Why did we intentionally leave out the information that GreenTurtle should be able to remember what attack it wants to use? )
11
- No-arg constructor: self-identity is G and is green. Random seed is 9. Right after it is born, it has a natural sense of direction to know it should go north first. It will be able to start counting from a value you set. (Where did the count instance variable come from?) It will also make the initial choice to roar.
- New method to deciding the move generateMove(): the GreenTurtle will randomly choose between the four non-center directions with equal probability. It will go through this thought process (i.e. call the generateMove method) if it wins a fight, right before it moves, and when it eats. Since the GreenTurtle eats only three times, there will be only three times when GreenTurtle thinks of its next move while eating. This method shouldnt take any parameter.
- Override generateAttack() method: The GreenTurtle will go through the thought process of choosing its next Attack when it mates, when it fights, and when it wins a fight. GreenTurtle will have a 10% chance to decide to roar and 90% chance of deciding to scratch.
- Override eat method: GreenTurtle will eat three times and then never eats again. This means that there is only three times where encountering food will cause the GreenTurtle decide its next direction. You should use the inherited count variable to keep track of it.
- Override fight method: The first thing GreenTurtle does is decide again what attack to use. THEN, if and only if the opponent is Sloth, the GreenTurtle will roar. BUT, if the Sloth is sleeping, then the GreenTurtle will forfeit. In the encounter, GreenTurtle will not overwrite what attack it considered before; the attack choice remains the same.
- Override win method: Upon winning, the GreenTurtle will decide its next direction and its next attack.
- Override mate method: Upon mating, the GreenTurtle will decide its next attack.
- Override getMove method: Prior to moving, the GreenTurtle will decide what direction one
more time.
12
Part 3: Inheritance Concepts [10 Points]
This part requires that the previous two parts are implemented and correct to our specification. In a new file called InheritanceConcepts.md, for each of the following questions, provide information about what happened, why you think that is happening, and use the concept of inheritance to support your answer.
You should create a new class file that will not be submitted for the sole purpose of having a main method defined in a class outside the Critter family. Declare and instantiate various Critters inside this new main method, and then try to find out as much as possible, based on your understanding of inheritance, for each of the questions. Each answer must be at least four sentences long, and at most six sentences long.
1. Suppose in the Critter.java file, I add an additional method. It is defined with the following pseudocode:
method sayStuff(): System.out.println(I am a Critter.);
How does that affect other Critters?
2. What is the fight behavior of SadAnimal? Explain why it is the case.
3. Suppose that I comment out getColor in HappyAnimal.java. What happens? Why does it happen?
4. In SadAnimal.java, suppose I add one more instance variable that is a public and static String. Who is affected, and what happened? Please also clearly explain why. Experiment (change it, add it, bop it) with this variable in your subclasses.
13
Part 4: Your Critter [20 Points]
In the latter half of your assignment, you will create your own Critter from scratch. There is no starter code, of course, because the implementation is entirely up to you. You may choose to write a class that extends from Critter, or any of the Critters from Parts 1 and 2. Your Critter can be named anything, with some conditions. The name, of course, must be appropriate. If you plan on entering the competition, do not start until you read Part 4.1.
Your objective is to create the ultimate Critter: one that can outlive and beat all other Critters in the World! It is the Survival of the Fittest! Will your Critter survive?
Your Critter must win in the following environments:
- A World with Sloths, Leopards, Turtles, and GreenTurtles.
- A World with Sloths, Leopards, Turtles, GreenTurtles, and Mystery.
Only the class file of Mystery is provided. There will be no documentation about this class. To find out what is the functionalities of this class, run it in the simulator and observe its behavior with other classes, including your own class. Use the Tick button if you like.
The conditions for a win is the following:
- The screen size is width = 60 and height = 50. There will be CritterCount = 25 of each Critter.
- At 1000 moves, the game is considered over. Even though the game will continue to run, we
specify that 1000 moves is the minimum time of the simulation.
- Your Critter must have the highest score and least one of your Critters must still be alive in the
World.
Three out of five simulation executions done by the grader must result in a Win for your Critter for full credit. Any less will be considered for partial credit based on the performance as seen by the simulator.
Remember, some outcomes are random, and the fighting system is 96% definitive. Therefore, you must do your best to strategize and ensure the highest possible probability of success for your Critter. Run simulations multiple times, and run simulations with different configurations. Continually run these tests and modify your Critter as needed.
14
Part 4.1: Your Critter, with Thousands of Others
There will be a competition between every Critter that all students submit. Therefore, we need a viable way of identifying your Critter. The filename needs to include your email address to be entered into the competition. An example is, if your email address is [email protected], then your filename might be Shuaiqi_s8xia.java (FirstName_email.java). Your Critters name will be the first part of the file name, followed by one underscore _, and then the username portion of your email address. If we cannot match your email address to your Vocareum submission email, it will not be entered.
In the competition, your Critter will compete against hundreds of other students Critters. We will run a simulation with many Critters from every student on a powerful machine with 64 Gigabytes of RAM to see whose Critter will come out on top. While strategy may be a large portion of probable success, luck is also a major portion. There wil el be only one run of the entire competition, with multiple instances of every students Critter inside the simulation.
May the odds be ever in your favor.
Part 5: Command Questions and Program Descriptions [10 Points]
In a new file called README.md, answer each of the following questions. Each of the questions is worth 1 point each. The program description is worth 3 points. The testing description is worth 5 points.
Java/UNIX/Linux Questions:
- Using the cut command, how do you extract out only columns 5 through 13 in a file named foo?
- How do you declare and instantiate an ArrayList that contains only Critters? (Dont worry about
adding Critters or any subclass of Critters to the ArrayList. We are only asking about declarations and instantiations.)
Write a paragraph about the entire Critters program itself. This program description should NOT be about each class related to the Critters. Thats the file and class headers job. Rather, the description should talk about what the simulator does, how the simulator reads files into its program, and how you change the settings to your needs.
Write a paragraph on how you tested your Critters. This section must be five to eight sentences long. Examples of your testing procedures might include what features of the Critter simulation you used to help you run your tests.
15
At this point, you have implemented Critters to our specification with our guidance in starter code, other Critters with hints from the writeup, and your own Critter you added to the Critter family. Now, for 10 possible extra credit points, you may implement with style a Dragon of our specification. The amount of work required for extra credit and the difficulty of this part are proportionally higher than normal credit.
For extra credit you will implement a new kind of critter called the Dragon. The Dragons will have different behavior from the other animals. The following are the details of its implementation:
- The dragon should choose a random attack (from ROAR, SCRATCH and POUNCE) when initialized.
- The dragon will change color depending on the food items that it consumes. If it has even number of food items, itll be black in color. If the dragon has odd number of food items, itll be white in color.
- When the dragon encounters an animal of a different species, it will fight. The choice of attack will depend on the PREVIOUS animal that it encounters. If previous attacker was Leopard or Sloth, attack ROAR. If previous attacker was Turtle or GreenTurtle, attack Pounce, else attack Scratch. The first attack is the randomized attack initialized when a Dragon object is created.
- The initial direction of the dragon is WEST. In the subsequent moves, the dragon goes in a zig zag circle shape of diameter 10, going in counter clockwise direction.
- The eating behavior of a dragon is always true.
- The toString method should return D
This is how the movement would look if you trace it
The two dotted lines are to show that the overall figure is of length 10 and width 10. You do not move along the dotted lines!
The move should start at the middle top and move in anticlockwise.
Check this video to see how the dragon moves:
16
Submission and Grading
The grading for the PSA will be slightly different from past PSA. The fight system has an inherent component of probability. Therefore, you need to ensure that your Critter performs with great strength in order to beat the odds. We run each students Critter with the scenarios as listed above. No regrade requests are accepted for rerunning the simulation. There will be five runs of the simulation. To be confident that your critter will win three times, you should ensure that your Critter can win in your simulations most, if not all, of the time. If the Critter loses twice in our test runs, that is the fail-safe for full points. Some partial credits may be given if your critter wins between zero to two times.
Starting with this assignment, we are expecting by default that code is written with good style. Refer to the style guidelines for more information, though it is unchanged. It is possible to lose up to ten points for bad style, but we are not allocating points specifically for style.
Start early, as most of the challenges might be in getting your code to match our specifications.
Submission Files (Make sure your submission contains all of the files and that they work on the ieng6 lab machines!)
README.md
InheritanceConcepts.md
SadAnimal.java
Sloth.java
Turtle.java
GreenTurtle.java
Leopard.java
FirstName_email.java (Shuaiqi_s8xia.java)
Maximum Score Possible: 110/100 Points
In addition to submitting the files required, make sure YOUR Critter is correctly named. Refer to above
for requirements. If your Critter (or any code for this matter) does not compile, we wont grade it. Make
sure to submit the correct files and that they compile and run on the ieng6 machines.
17
Reviews
There are no reviews yet.