Introduction to Computer Science II by James Tam Return to the course web page

CPSC 233: Assignment 5

New concepts to be applied for the assignment1

  1. Inheritance
  2. Casting within an inheritance hierarchy
  3. Method overriding & Polymorphism

[JT's hint: The final exam will include a question or questions relating to material in the 'hierarchy' section. The  question(s) be drawn from the three new concepts introduced in this assignment (and likely other topics such as implementing interfaces). Consequently I strongly recommend that if you don't have time to attempt all the major features of the assignment that you at least attempt features that require the application of all of the above topics.]

Introduction

Computer simulations are re-creation of a real-world scenario. Simulations are important for many reasons including (but not limited to) safety and cost. Also simulations may assist in decision making by allowing alternatives to be tested before a course of action is chosen. For this assignment you are to implement a simple wildlife simulation. There will be three types of life forms that live in this simulated world: prey, flying predators and ground-based predators. Prey procreate. They may be injured by predators but they can slowly heal their wounds over time. Prey that have been critically injured by predators will die and vanish from the simulation. Predators will attack prey that are nearby. All three life forms can move randomly about the simulation although flying predators have the greatest range. The program will maintain statistics on the number of prey that are born into the simulation, and the kills and damage inflicted by the different types of predators. The simulated world will be represented in the form of a 2D array of "SimObjects" (the parent class of all the entities in the simulation).

Required classes for this program

Pre-created classes that you must use (see the 'resources' section) Classes that you must implement
SimObject Driver
Coordinate Simulator
Animal Biosphere
Predator Prey
Mode Flyer
FileBiosphere (class file) GroundBased

Pre-created classes

SimObject: represents all the objects in the simulated world (living or non-living). Although this version of the simulation only includes three types of living objects later versions of the program could include physical non-living objects (e.g., trees, grass, rivers etc.). These other types of objects would be instances of class SimObject. Each instance of the class will have an appearance attribute. This class will have a class constant that determines the default appearance of the object (a space). Each child class should have its own class constant to indicate the default appearance of the instances of that class e.g., class GroundBased { public static final DEFAULT_APPEARANCE = 'G'; ... }

Coordinate: each location (array element) in the world can be described by a row/column pair. In the previous assignment you could have used two integers. For this assignment some methods will generate and return a location (e.g., class Prey's move method) it's easier to return the row and column value as a single coordinate rather than as two separate integer values. (Recall methods only return a single value).

Animal: a child class of SimObject, it represents living and moving occupants of the world. Consequently instances of this class will have three attributes: the current row/column coordinate of the animal and a boolean flag that indicates whether the object has moved yet during the turn. Additionally animals have methods that allow them to move (randomly generates a value that determines which of the adjacent squares that it will attempt to move to - the Biosphere class will determine whether that location is a valid one: is it in bounds and is it empty).

Predator: a child class of Animal that represents all the animals that consume prey. It has a class constant that indicates the amount of damage that its attacks do and a method that generates the attack damage that it inflicts on prey. (The prey would then use this value to reduce its health). Instances of class Predator only do a fixed amount of damage with each attack but it's child classes: Flyer and GroundBased inflict variable damage.

Mode: It will be defined as follows:

public class Mode
{
     public static boolean debug = false;

}

Similar to the previous assignment the purpose of this class is used to control the appearance (or absence) of debugging messages.

FileBiosphere:  Similar to the file class from the previous assignment this static class will allow your program to read the starting positions from an input file called "input.txt". In this case it will read the information from the file and instantiate the appropriate SimObject in the array attribute of Biosphere. To use the code in this class file however you need to make certain that you follow all design requirements (e.g., classes must implement a constructor with a precisely defined method signature).

Classes that you must implement

Driver: the starting execution point and it should contain a reference to an instance of class Simulator so the simulation can be started.

public class Driver
{
     public static void main (String [] args)
     {
          Simulator aSimulator = new Simulator ();
          aSimulator.run();
     }
}

Simulator:  this class acts as the 'manager' for the simulation. It controls when the simulation starts and when it ends as well as determining the order of each sub step in a turn. (Similar to the Menu class from A3 which called methods of class Manager, class Simulator will call methods of class Biosphere in order to execute the sub steps such as displaying the world...the simulator determines what sub step occurs when, and then it calls the appropriate method of class Biosphere). Since the user interaction is extremely minimal (for the debug toggle) it can also process user inputs as well.

Minimum required attributes: a reference to an instance of class Biosphere.

Minimum required behaviors: all the functionality with running the simulation itself (start, end, running each sub step) and the user interface.


Biosphere
: Similar to class Forest in the previous assignment. The Biosphere tracks information associated with this particular simulated world, a savannah.

Minimum required attributes: an array of references to SimObjects (more specifically instances of the child classes: Prey, Flying, GroundBased). Other attributes include the statistics to be tracked in this particular simulations: prey births, damage and kills inflicted by the flying and the ground based predators. Array elements will consist of references to SimObjects (prey, flyer, ground based) or it will be null.

Minimum required behaviors: methods that change or retrieve information about the attributes e.g., displaying the world, checking array bounds, births, deaths, movement etc.

Prey: A child class of Animal. It moves, procreates, heals and (perhaps) dies.

Minimum required attributes: information about it's current health level (12 is full health, 0 is dead). Also a flag is needed that indicates whether the prey is new born. An object stays newborn during the turn in which it was born (see feature #10) after which it may participate in the birth of new prey. Default appearance of prey is 'r'.

Minimum required behaviors: the ability to heal wounds inflicted by predators. Note: dead prey are removed from the simulation and don't heal. It also must have a constructor that takes the following parameters: a character and two integers. The first parameter will be used to set the appearance attribute, the second parameter will set the row attribute and the third parameter will set the column attribute: Prey (char anAppearance, int aRow, int aColumn)

Flyer: A child class of Predator. Flying predators inflict a different amount of damage from the parent predator and have a wider range of movement.

Minimum required attributes: none.

Minimum required behaviors: three overridden methods: attack(), positionToCoordinate () and move (). Flying predators inflict 2 - 8 points of damage per attack. They are not limited to moving to adjacent squares (range 1) but have maximum range of 2 squares e.g., if a flyer were on row 3 then the maximum distance it could move 'up' would be row 1 and maximum distance that it could move down be to row 5. Similar to class Prey, this class also must have a constructor that takes as input a character and two integers.

GroundBased: A child class of Predator. Ground based predators are larger and more powerful than the typical predator. Default appearance is 'G'.

Minimum required attributes: none.

Minimum required behaviors: one overridden method: attack(). To reflect their increased size and strength ground based predators inflict 3 - 10 points of damage per attack. You need to override the attack method so it generates and returns a number within this range. Similar to class Prey this class must also have a constructor that takes as input a character and two integers.

Providing an overview of your program's classes and their relationships

You will need to create a UML class diagram that specifies the full information about the classes in your program (method signature and return value, method attributes) as well as the relationships between classes. Your diagram should not only include the classes that you implement yourself but also the required classes that I created.

Program features (you will also be graded on other criteria such as style and documentation as listed in the marking key):  After creating the above class definitions here are features that should be included in a working program.

Note: the marking key for this assignment will be set up so you can get a top grade without necessarily implementing each and every feature (there will be a margin of error built in). However in order to prepare yourself for the exam make sure you attempt (better yet complete) a set of features that apply each of the new concepts introduced in this assignment.

  1. Displays an introduction to the program that describes the rules. It only displays these instructions right after the program is run.
  1. Displays a sign off exit message when the program ends.
  1. Reads the starting positions from file or uses the hard-coded constructor. (Similar to the previous assignment the first case yields a better grade). Empty squares will be set to null. Occupied squares will contain references to prey, flying, or ground based predators.
  1. Displays the world with a numbered grid and the current turn.
  1. Simulation runs for fixed duration (user specified number of turns).
  1. Each sub-step of a turn has been implemented in the order listed below. The program may pause and wait for user input before proceeding to the next sub step.
  1. At the end of each turn the program will pause before continuing onto the next turn. At this stage the user may toggle debugging mode on or off  (by entering 'd' or 'D'). When debugging is toggled the program should indicate what mode the program is operating under (e.g., "Debug mode turned off"). The exact content of the debugging messages are left to your discretion, to get credit for the feature you just have to make a reasonable effort to show that you used this feature to test and debug your program (i.e., using the mode in only a method or two won't be sufficient for full credit).
  1. Wounded prey can heal. This is based on the health attribute which ranges from 0 - 12. Fully healthy prey are at twelve and won't heal. Prey whose health ranges from 1 to 11 will heal one unit per turn. Prey whose health is zero or less are counted as dead and will be removed from the simulation.
  1. Prey can move to a random, empty and adjacent square (range is one). For each square within range (and the current square) there is an equal probability (uniform distribution) for a particular location to be chosen.2 To get credit for this feature you won't need to write new methods for class Prey. You can and must use (use = call from another classes methods) the existing methods of class Animal: move () which generates a position from 1 - 9 and this position will be used to generate an instance of class Coordinate (which has a row and column attribute).  The method positionToCoordinate () will take the position as input and return an instance of class Coordinate.
  1. Prey can procreate. The conditions for reproduction are as follows. Each empty square that has two prey (not newly born) in adjacent squares will have a new prey animal born into it. This animal is considered a newborn for this turn and cannot be used to produce new prey until the next turn.
  Before After
 
Prey   Prey
     
Prey    
Prey <Birth> Prey
<Birth> <Birth>  
Prey    
  1. Ground based predators can move to a random, empty and adjacent square (range is one). Much like prey the probability of movement to any square within range is equal.2 Again you won't write new code in class GroundBased to move the predator, instead you are to use the existing methods of class Animal: move (), positionToCoordinate ().
  1. Flying predators will randomly move to an empty square that is within their range of motion (two squares). Similar to ground based predators, the probability that a particular square within range will be picked is the same for each location. The difference is that a flying predator has a greater range so the number of possible destinations is larger). [JT's hint when trying to figure out what/how many squares are within range try drawing out a grid where you can move up to two squares in any direction.]2 Unlike class Prey and class Flying, to get credit for movement you will have override method: move () and positionToCoordinate () in class Flyer. That is because in the case of prey and ground based predators their movement behavior wasn't any different from the base animal so instances of these classes can just use the parent's methods. Since the movement of flying animals is quite different, instances of class Flyer require their own overridden methods.
  1. Predators attack. The parent predator class already has an attack() method implemented. To get credit for the flying predators attack feature you must override this method in class Flyer so that the flyers inflict 2 - 8 points of damage. To get credit for the ground predators attack feature you must override this method in class GroundBased so these predators inflict 3 - 10 points of damage. A predator will only attack a prey object which is in an adjacent square. It won't attack multiple prey even if more than one is adjacent. You can choose the algorithm (random or a fixed) to determine which prey gets attacked if more than one is adjacent. Prey that are killed should be immediately removed from the simulation (it won't be attacked by another predator).
  1. Display statistics: number of prey births, number of prey killed by predators (by kill it means the first predator that brought a particular prey animal to zero or fewer health) and the health points (damage) inflicted by predators. The latter two statistics will be each subdivided by predator type (i.e., flying prey kills vs. ground based kills, flying prey damage vs. ground based damage). Statistics should be shown at the start of each turn. That of course means that as events occur (births, damage, deaths) that information must be tracked.
  1. Additional bonus feature: instead of displaying the simulation in text, a graphical library (e.g., Java 2D, QuickDraw is used). The interface itself can still be console based (i.e., hit enter to continue) just the output can be graphical. Your graphics don't have to be fancy (e.g., you can use different primitives, color and/or text to distinguish the types of animals) but the graphical version must clearly represent the same information as the text-based equivalent (e.g., don't use rectangles of the same size and appearance for each type of animal). You won't get a lot of extra marks for implementing this feature (because graphics isn't a key feature of this program) and you will either have to be familiar with a library or be willing to invest the time to learn one on your own. But I did include this feature in case you wanted to spice up your program and/or you wanted to increase the probability that your assignment received a higher grade.

2 To make it simple you can use the following approach for determining which animal to move. Start at the left hand corner of the simulation. If there is an animal there move it. Now based on the current state (animal moved) work along that row from left to right moving the animals. The new location of animals that have moved should be treated as being occupied to animals that move later (but it's source will be treated as empty). Then move down to the next row and again move from left to right. Repeat until the square at the bottom right has been reached.  Although all movements for prey or predators are all finished before the world is displayed, the program needs some rules for determining the order of movement (i.e., you can't have two animals moving into the same square during one turn). Consequently that means that movement is checked from top to bottom, left to right in order to resolve collision conflicts.

Time passing (turns): your program must be implemented in the following fashion

During each turn the following things will occur in the following order:

Resources:

They can be found in the UNIX directory: /home/233/assignments/assignment5. Within this directory are three sub-directories: 'data', 'java_code', 'sample_runs'. The first directory contains different versions of input files that you can use for your assignment (Useful for testing different features, feel free to make your own. Just rename each file to "input.txt" when you want the "FileBiosphere" class to use it as input. Keep in mind each file must be 10x10 in size.) The program that you submit for marking must be able to handle the base file "input.txt").  The second directory contains the dot-java and the one dot-class file that is needed by your program. The third directory contains text files that show the output of my solution program under different situations. Since there is no byte code solution to run for this program you can look through the output of these files to clarify assignment requirements.

Submitting your work:

  1. Assignments (source code/'dot-java' files) must be electronically submitted according to [the assignment submission requirements]. For this assignment you need to create a UML class diagram that shows: the classes implemented, their relationships as well the attributes/methods and their access permissions. Individual classes must show the 'full information' for each method (parameter names and types as well the return type). Class diagrams can be drawn by hand and scanned, or drawn electronically. Also you need a README text file that lists which of the features of the assignment you have completed. If there are any special instructions needed to run your program, e.g., images needed, the instructions should be included in the README file and these additional files submitted as well. You are to electronically submit the class diagram, README file along with your source code (make sure you don't forgot to submit all the dot-Java files). There is no need to compress the files via zip or another program.
  2. As a reminder, you are not allowed to work in groups for this class. Copying the work of another student will be regarded as academic misconduct (cheating).  For additional details about what is and is not okay for this class please refer to the following [link].
  3. Before you submit your assignment here is a [checklist] of items to be used in marking.

External libraries that can be used

  1. Libraries that allow for text-based (console) input and output.
  2. Classes used to generate random values such as Class Random or class Math.
  3. (If the last feature is implemented).  Java libraries that draw two-dimensional graphics.