ulrail.gif

HW 8: Class Creation II

  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 another 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 9): This class provides a number of methods that allow the game to progress (such as handing the turns, ending the game, etc.)
  • Depot (hw 8): 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 Inventory and Depot classes.  You must submit these two files, along with the Game.java file.  We are providing some skeleton code for Depot.java. We've given you the implementation for the sellItem() method and commented guidance for enterDepot() and buyItem().  No skeleton code is given for Inventory.java.

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 several of the other classes to complete this homework:

  • Location.class:  You implemented the Location class in hw7. You are welcome to use that version, or the version provided in the link here.  Documentation on the available methods and constructors for this class are available at the course project documentation site
  • Parser.class: You implemented this class in lab 9.  Information on this class is available at the course project documentation site. We have provided you with a fully-implemented, pre-built class with the following methods implemented that are needed for this portion of the project:
    • int parse(): parses user input and returns the corresponding command code.
    • int getInteger(): returns the int entered by the user.
    • int getItemToTrade(Inventory theInventory, double priceFactor): Prompts the user for the item they wish to trade.
  • Descriptions.java:  This file currently contains generateRandomDepotName() and getPropulsionName(). (Descriptions.java will be implemented in lab 10.)
  • Party.java:  This file currently contains a default Party constructor and no properties.  (Party will be implemented in hw 9.)
  • Vehicle.java: This file currently just has a few methods implemented to allow you to develop the Inventory and Depot classes.  It contains a default Vehicle constructor, getLocation(), and getInventory() methods.  (You will augment and complete Vehicle.java in lab 10.)

Unless otherwise specified, no methods (other than the main() method in Game.java) should be static.

Game class

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

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.

Inventory class

The first class you must implement represents the inventory or stock.  Nothing should be static, all fields must be private, and (unless specified otherwise), all methods public.  Your Inventory class needs to be declared public, and in a Inventory.java file.

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

Properties

The Inventory class has a number of instance properties:

  • int food: This will hold the amount of food in the inventory. The default is 0.

  • double money: This will hold the amount of money in the inventory.  The default is Game.STARTING_MONEY.

  • int ammunition: This will hold the amount of ammunition in the inventory.  The default is 0.

  • int oxen: This will hold the amount of oxen in the inventory. The default is 0.  Note that although we call it oxen, it will represent one unit of propulsion -- you will be able to name it anything you want later on (horse, rocket booster, sedan chair porter, etc.).

In addition to the above properties, the Inventory has a number of class properties that are used as constants.  There is one of each for the class, instead of a set for each object, so they should be static.  Because these fields are final variables, they should be private.

  • final int MONEY_POS: This constant corresponds to the selection of money from the inventory. It is used by many of the Inventory class methods to identify a user's choice.  This should be set to 0.

  • final int FOOD_POS: This represents the selection of food from the inventory. It is used by many of the Inventory class methods to identify a user's choice.  This should be set to 1.

  • final int AMMO_POS: This represents the selection of ammunition from the inventory. It is used by many of the Inventory class methods to identify a user's choice.  This should be set to 2.

  • final int OXEN_POS: This represents the selection of money as an item in the inventory. It is used by many of the Inventory class methods to identify a user's choice.  This should be set to 3.

  • final int NUM_ITEMS: This represents the total number of distinct types of items in the inventory.  It should be declared with a value of 4, since the inventory currently supports 4 categories of items: food, money, ammunition and oxen.

Constructors

There are two 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.

  • Inventory(): This constructor sets the Inventory properties to their default values.
     
  • Inventory (int theFood, double theMoney, int theAmmo, int theOxen): This constructor checks the passed parameters for valid values, then sets the corresponding properties in the inventory to those 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. getAmmunition(), setAmmunition(), 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 eight other methods that are required for this class. 

  1. double getCost(int item, double priceFactor): This method should return a double which represents the current market cost of the item specified. The item's cost is the product of its default value multiplied by the priceFactor.  The costs for different inventory items are defined as final variables in Game.java.  Recall that each item in the inventory has an int field that specifies which item is being referred to; the associated cost should be returned.
     
  2. int getAmount(int item): This method will return an int that returns the amount of food, ammunition, or oxen that is available in the inventory.  getAmount() should not be allowed on money, even though it is an item in the inventory.  Remember to use the accessor methods and handle "bad" conditions.
  3.   Note that the item parameter will be one of MONEY_POS, FOOD_POS, etc.  Note that three of the fields are ints, and thus are returned by this method; you cannot get the amount of money by this method (you can just print an error message and keep going).
     
  4. int getNumItems():  This method returns the maximum number of valid items in an inventory.  It returns the value of the constant NUM_ITEMS.  This method should be static.
     
  5. void remove(int item, int amount): This method should remove amount of the specified item from the inventory. No value is returned.  Note that the item parameter will be one of MONEY_POS, FOOD_POS, etc.
     
  6. void remove(int item): This method removes all of a specified item from the inventory.  It should call the 2 parameter remove() to do so.  No value is returned. 
  7. Note that the item parameter will be one of MONEY_POS, FOOD_POS, etc.
     
  8. void add(int item, int amount):  This method adds amount of an item to the corresponding item in the inventory.  No value is returned.
  9.   Note that the item parameter will be one of MONEY_POS, FOOD_POS, etc.
     
  10. void printInventory(double priceFactor, boolean showMoney):  This method prints an itemized listing of the current market value of the inventory using priceFactor.  In other words, the value of the inventory is the amount of that item multiplied by the item's default cost multiplied by the priceFactor. If showMoney is true, the total amount of money is also displayed.  (Money is not subject to a market value).


  11.  
  12. void printInventory(double priceFactor):  This method prints the inventory assuming that money values should be shown.  It should call the 2-parameter printInventory() method with showMoney set to true.

Depot Class

The second class you must implement is the Depot class.  Objects of this class serve as marketplaces for the game and are associated with particular locations on the game map.  We have provided you with a skeleton Depot.java file.  It contains the implementation for buyItem() and comments to guide you through writing enterDepot() and sellItem().

All methods should not be static.  Unless specified otherwise, all methods must be public.

Properties

The Depot class contains a number of properties.  They are:

  • double priceFactor: This property represents the market rate for goods at this depot. The price factor can vary from depot to depot.  The default value for the price factor is 1.0.
  • Location myLocation: This property represents the location of the depot.  The default value for the location should be null.
  • String name: This is a String which is the name of the depot. For instance, "Ma's Hometown Store" could be a name for the depot.  The default value for name should be the empty string, or "".
  • Inventory myInventory: This property represents the inventory available in the depot.

Constructors

You will write 2 specific constructors for Depot:

  • Depot(Location theLocation): This constructor sets the location property to theLocation, initializes the name property to a randomly generated String returned by Descriptions.generateRandomDepotName(), and initializes the inventory to a new inventory object whose initial values are the default constant amounts for food, oxen, and ammunition (money is initialized to zero).

  •  
  • Depot(double theFactor, Location theLocation, String theName): This constructor sets the corresponding properties to the parameter values passed.  In addition, it initializes inventory to a new instance of an inventory with the same default values as the constructor above.

Accessors and Mutators

You will need to write accessor and mutator methods for all the properties of the Depot class.  They should have appropriate names, such as getName(), setName(), getLocation(), setLocation(), etc.

Other Methods

There are four methods that should be implemented for the Depot class.

  1. void printDepotCommands(): This method will print the list of depot command options in menu format with brief descriptive text.  No values are returned by this method, only descriptive text is printed to the display.  This method should print the following options:
    • buy - This is the option selected when buying is desired.
    • sell - This is the option selected when selling items is desired
    • available - This command option, when selected, will print the available items from the Depot's inventory
    • inventory - This command option, when selected, will print the inventory that belongs to the player's party.
    • exit - This option describes the command to leave the depot and return to the location.
     
  2. void enterDepot(Vehicle player): This method will return nothing and performs the actions associated with being inside the depot.  Remember that your code should handle "bad" values. 
    1. Print a descriptive welcome message to the party and describe the price factor for the depot. 
    2. Then, the user/player should be repeatedly be presented with the possible depot commands.  The commands are extracted using the Parser.parse() which returns an int corresponding to one of the depot commands.  The constants for these commands are also defined in Parser (and are called Parser.BUY, Parser.SELL, Parser.AVAILABLE, Parser.INVENTORY, and Parser.EXIT_DEPOT) and should be handled as follows:
      • buy - calls buyItem(), then prompts the user for another choice.
      • sell - calls sellItem(), then prompts the user for another choice.
      • available - calls the 2-parameter printInventory() method with the current price factor.  The Depot's money inventory should not be printed.
      • inventory - prints the player's inventory
      • exit - leaves the enterDepot() method and therefore leaves the depot.

     
  3. void buyItem(Vehicle theVehicle): This method handles all the tasks related to buying an item at the depot.  Comments have been provided in the skeleton code to help guide you through writing this method.  Due to incomplete implementation of the Vehicle class that was distributed, you will be unable to test the buyItem() method.  Points will not be deducted for this.
    1. Prompt the user for an item choice. Calls Parser.getItemToTrade().  The player will enter a text selection (e.g., "buy"), which the Parser will convert to a corresponding int value.
    2. Prompt the user for an amount.
    3. If a valid item is selected, then prompt the user for an amount to buy and read the value in using Parser.getInteger().
    4. Calculate whether the buyer has sufficient funds for the purchase. If the amount is a valid amount, then calculate whether the buyer has enough money to purchase the amount they desire.  This is calculated by taking the product of the price factor, the cost of the item, and the amount requested by the buyer.
    5. Perform the buy. If the buyer has sufficient funds, then add the amount of that item to the player's (Vehicle) inventory, remove the same number of that item from the depot's inventory, and add the money equivalent to the total price to the depot's inventory.
       
  4. void sellItem(Vehicle theVehicle): This method handles all the tasks related to selling an item at the depot. The implementation for this method has been provided for you in the skeleton code.
    1. Prompt the user for an item choice. Call Parser.getItemToTrade(). 
    2. Prompt the user for an amount.
    3. If a valid item is selected, then prompt the user for an amount to sell.
    4. Calculate the value of the items being sold. If the amount is a valid amount, then calculate cost of the items.  This is calculated by taking the product of the cost of the item, and the amount available for trade.
    5. Perform the sell. The cost is added to the player's (Vehicle) inventory, the items are moved to the depot's inventory, and removed from the player's inventory.

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 has more constants than previous versions of Game.java.  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 Inventory'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.

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 yourrr 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 Inventory.java, Depot.java, and Game.java files.

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