ulrail.gif

HW 7: Class Creation

  ur-2c.gif urrail.gif
blrail-nonavbar.gif

Home | Resources | Homeworks | Exams
Lectures | Labs | Contacts | Submit | TAs

br-2a.gif   br-2c.gif brrail.gif
spacer.gif spacer.gif

Course Project

This homework is the first part of the course project, which is to implement a modified version of the Oregon Trail computer game.  If you are not familiar with the game, then you should read the article at that link.

There are a number of classes that will be required for this project, split among the next few homeworks and labs.

  • Control (hw 8): This class provides a number of methods that allow the game to progress (such as handing the turns, ending the game, etc.)
  • Depot (hw 9): This is a "market" (fort, etc.) that can occur at a location.  You can buy and sell goods at a Depot.
  • Descriptions (lab 10): This class allows you to customize the game -- you choose the names for various things in the game, such as the party members, the name of the vehicle, etc.
  • Game (all assignments): This class has the main() method that will run the game.
  • Inventory (hw 8): This class represents the inventory that holds items.  Every depot, as well as the player's Vehicle, will have an inventory.  It holds such things as food, money, and oxen.
  • Location (hw 7): This class represents a location on the map.  A Location has a given type of terrain, and can have a Depot.
  • Map (hw 10): The 2-D grid that composes the board of the game.  It's a 2-D grid of Locations.
  • MapPrinter (lab 11): This class will print out the Map to the screen.
  • Parser (lab 9): This class is in charge of obtaining all user input.  No user input is read in in any other class.
  • Party (hw 9): This class represents a party of people that are traveling.  There will be 5 or so people per party (i.e. you are leading a group of 5 or so people).
  • Person (hw 7): This class represents a single person in the game.
  • Vehicle (lab 10): This class represents the player's vehicle.  The vehicle contains the party (i.e. all the people that are traveling), as well as an Inventory (how much food, etc. the player has).

Don't worry if you don't understand all of what these classes do (or why they are all needed!) at this point -- it will become more clear over the next few assignments.

Purpose

For this homework, you are responsible for implementing the Location and Person classes.  You must submit these two files, along with the Game.java file.  We are not providing skeleton code for Location.java and Person.java.

A note about the due date

We got this homework out a bit later than expected.  In an effort to compensate, we made this assignment a bit easier.  Other than the constructors and accessors/mutators, there are only 5 methods that you need to implement (three in Location, two in Person).  Also, we have provided a lot of test code in Game.java that tests the Person class (you only have to provide, in Game.java, the test code for the Location class).  If you still think this is totally unfair, and need to vent your wrath at somebody, please come speak to one of the two instructors in person (wrath is much more interesting when vented in person, rather than by e-mail).

Getting Started

Most of the classes in this project are dependent on other classes.  For that reason, you will need to download skeleton code for a few of the other classes to complete this homework:

  • Control.java: This file currently just has the possiblyEndGame() method, which is called in the Person.changeHealth() method. (You will augment and complete Control.java in hw9.)
  • Depot.java: This file currently just has a specific constructor, which is called in the Location constructors. (You will augment and complete Depot.java in hw9.)
  • Descriptions.java: This file currently has two methods.  The first, getTerrainTypeName() is called in Location.toString().  The second, generateRandomTerrainAdjective(), is called in the Location's default constructor.  This class is described more below.

Note that the ONLY thing in this homework that should be static is your main() method in the Game class.  If anything else is static, you are doing something wrong.

Game class

We provide a Game.java file, which includes a number of things that you will need for the homework.

Random Values

To choose a random value, you will need to use the Random class.  We have provided a object of class Random for you to use.  YOU MUST USE THIS ONE, as we will need that for testing and grading.  In order to create a random integer, you would call Game.random.nextInt(x), where x is any integer value.  This will return a random number between 0 and x-1.  So if you call Game.random.nextInt(15), it will return a random number between 0 and 14.  You can choose a random boolean via Game.random.nextBoolean(), etc.

Game constants

The Game class also defines a number of constants that will be used in this project; only a few will be needed for this homework.

main() method

You will have to modify the main() method, as described below.  You should read the homework through before you begin, as completing the main() method will be easier if done while developing your Location and Person classes.

Descriptions class

This class is responsible for generating the names and types of terrain in the game, which are used in the Location's default constructor, below.  You will be implementing the Descriptions class in lab 10.  In the meantime, the one we provide has two methods that are needed for this assignment:

  • static String generateRandomTerrainAdjective(): This method will return a String that is the text description of a particular type of terrain (such as cloudy, wet, rainy, sunny). 
  • static String getTerrainTypeName(int terrainType): Given the type of terrain passed as an int, this will return a String that describes the terrain, such as grassland, mountain, forest.

Because the methods are static, you need to call them by the class name, not the object name.  Thus, to find an adjective for a particular terrain, you call Descriptions.generateRandomTerrainAdjective().  This returns a String.  To find the description of the terrain type, you call Descriptions.getTerrainTypeName(), passing in the type number of the terrain whose name is needed.  This method also returns a String.

Once you finish your Descriptions.java file in lab 9, you can use that instead of the Descriptions.class file that we provide.

Location class

The first class you must implement represents a single spot on the game board.  As with the Person class, nothing should be static, all fields must be private, and (unless specified otherwise), all methods public.  Your Location class needs to be declared public, and in a Location.java file.

Nothing should be static.  All fields must be private.  Unless specified otherwise, all methods must be public.

Properties

The Location class only has a number of properties:

  • String appearance: This will hold the appearance, such as "rainy", "cloudy", etc.  Default can be anything ('blank', for example).

  • Depot depot: This will hold the Depot (market) that the Location may or may not have; it is null if there is no Depot (that's also the default).

  • int posRow: The row (i.e. y coordinate) of the Location on the map; default is 0

  • int posCol: The col (i.e. x coordinate) of the Location on the map; default is 0.

  • int terrainType: The terrain type, it can be one of four or so options (grassland, mountains, forest, etc.).  Default is Game.TERRAIN_UNSET.

  • boolean isVisited: Whether the square has been visited by the player.  Default is false.

Constructors

There are three constructors for this class. Your constructors should call the mutators instead of setting the fields directly!  You may explicitly initialize the instance variables when they are declared, of course.

  • Location(): This constructor will do four things:
    • Set the fields to their default values
    • Call the chooseTerrainType() method, described below.
    • Select a random appearance via the Descriptions.generateRandomTerrainAdjective() method
    • Select if a depot is present.  Any location will have a depot if a random double value is less than Game.DEPOT_CHANCE.
       
  • Location (int r, int c): This constructor does everything that the default constructor does, but also sets the row and the column to the passed values.
     
  • Location (int terrain, int r, int c, String app, Depot dep): This constructor simply sets the object's fields to the passed values.

Please make sure you understand what each of these constructors does -- if you don't, then you will have trouble with the rest of the assignment.

Accessors and Mutators

Your class needs to have an accessor and mutator for EACH of the properties listed above.  The methods must following the standard naming scheme (i.e. getDepot(), setTerrainType(), etc.).  As discussed in lecture, your mutators should also check for "bad" values.  You have a number of options to do when you find a bad value:

  • Ignore the bad value, and set the field to some default and valid value
  • Print out an error message, and then set the field to some default and valid value

Exiting the program would normally be allowed, but it will cause our testing of your program to not work as well, so please don't exit the program when a bad value is found.

Other Methods

There are three other methods that are required for this class.  Note that the chooseTerrainType() method is private.

  • double getTerrainMovementCost(): This method should return a double which represents the cost of moving across a particular type of terrain. The costs for movement are defined as final variables in Game.java.  Recall that each location has an int field that specifies what the terrain is; the associated terrain movement cost (from Game.java) should be returned.
     
  • String toString(): This method will return a String that describes the Location.  This String should contain (in this order) the appearance, the terrain, its x-y position on the grid, and whether or not a depot exists at the location.  An example of such a String returned is, "hilly forest at coords (9,9) (has depot)" -- but yours can look differently, as long as the same information is still there.
     
  • void chooseTerrainType(): This method should generate a random double value and use this value to determine the terrain type.  If the generated random number is less than the density value for forests (declared in Game.java), then the terrain type should be set to the value for forest.  Otherwise, if the random value is less than the sum of the density values for forest and mountain, then the terrain type should be set to mountain.  Otherwise, the terrain type should be set to grassland.
     

Person Class

The second class you must implement is the Person class.  Objects of this class will be created to represent each of the people in your party.  Your Person class needs to be declared public, and in a Person.java file.

Nothing should be static.  All fields must be private.  Unless specified otherwise, all methods must be public.

Properties

It should have the following properties.

  • String name: The name of the person, it can default to anything ("John Doe", etc.)
  • int health: The initial health of the person, it should initially be set to Game.MAX_HEALTH.

  • boolean isAlive: Whether the person is alive or not; it should start as true.

Please make sure you understand what each of those properties does -- if you don't, then you will have trouble with the rest of the assignment.

Constructors

Your Person class should only have one specific constructor (and no default constructor).  Your constructors should call the mutators instead of setting the fields directly! You may explicitly initialize the instance variables when they are declared, of course.

  • Person (String name): Initializes two of three fields to their default values and sets the Person's name to the passed parameter.

Accessors and Mutators

Your class needs to have an accessor and mutator for EACH of the properties listed above.  The methods must following the standard naming scheme (i.e. setHealth(), getName(), etc.).  Your mutators should check to make sure that the variables are not set to invalid values!  For example, you can't set the health to greater than the maximum health value, etc.

Other Methods

There are two additional methods that are needed for the Person class.

  • void changeHealth (int byHowMuch): This method will modify the health property of a person by the amount specified by the variable byHowMuch. In other words, if changeHealth(5) is called, the person's health would be set to the current health value plus 5.  If the resulting health of the person is negative, the method should set the person's isAlive property to false.  Also, if somebody does die, then Control.possiblyEndGame() should be called (that method will check to see if everybody is dead, and if so, end the game).
     
  • String toString(): This method will return a String which contains the name of the person and whether or not they are alive.  A sample string would be "Chris Doe with health 8/10" or "Pat Doe who is dead".

Game class, Revisited

Your main() method in the Game.java file should test all of the methods that you implement.  You will notice that it currently tests all of the Person methods.  The basic idea is to call a method, and verify that it does what it was supposed to do by calling an accessor method.  For example, by calling the Location's specific constructor, it is supposed to set a number of values.  You need to verify this by calling the accessor method, and checking to see that they return the right values.  You can use specific values for these tests -- i.e., you can create a Location whose appearance is set to a String 'foo', and then check to see that the appearance of the Location's appearance is indeed 'foo'.

Where to Start

Work on the methods one by one, making sure that each one works before moving onto the next one.

While the main() method may seem like a lot of work, there are a couple of things that will make it much easier.  If you add the code to Game.java as you go along, it will make it much easier.  The idea is to implement a method or two, and then add the test code to Game.java.  Then make sure it compiles and works properly.  Then go onto adding more methods.  If you get stuck in a method (i.e. can't get it to work, it won't compile, etc.), then move onto another one, and come back to the one that is giving you problems.

Also note that the code for the testing of the accessors and mutators is going to be very similar -- you can just copy-and-paste the code, then modify it to use the other accessors/mutators.

Lastly, this homework will be much easier if you work through it one method at a time.  Write the first method, and then sufficiently test it in your main() method.  Then write the second method, and sufficiently test it in your main() method.  This will make the entire homework much easier, and it will take much less time to complete.

Good Programming Practices

All the good programming practices from HW 1 should be included here as well.  Since you are providing code in the main() method of the Game class to test your other code, you don't need to include execution runs as comments.

Submission

When you are finished, submit the Location.java, Person.java, and Game.java files.

spacer.gif
spacer.gif footer-middle.gif spacer.gif