COP-2805 Project #5 - Unit Tests (and Implementation) for Mini-Golf Project, Part II

 

Due: by the start of class on the dates shown for Part A and Part B on the syllabus

Overview

After evaluating the various designs and proposals, the customer had picked our organization to deliver the final project!  They have also provided input on the overall design, which we must follow.

Below are some design notes, including the classes to have and the methods required for each.  NOTE!!  You may add additional classes and/or methods to this basic outline.  (You probably will need to!)  Note the fields for the classes aren't specified here; this is considered an implementation detail.

For this version assume all code runs on a single JVM.  However each swipe-station runs on it's own thread, so any shared data must be made thread-safe.

The swipe card holds (for this initial version anyway) the player's name and the course name only.  Somehow you need to look-up the player's Round object (see class Round below).  This information does not need to be stored except in RAM.  The Main class will need to provide a getRound method that returns a Round object (or null) given a player's name and a course's name.  This implies the two implementation teams will need to communicate and cooperate.

The Two Primary Classes

For the initial version we can find many candidate classes, but in the end only a few are needed to meet the requirements:

  1. Class Round

    Class Round holds a player's information for the current round of golf: their name, the course name, and the number of strokes per hole (for each hole played so far).  An object of this class is created when a customer pays for a round and their name is entered by the operator, which also creates a swipe-card.

    The round information is not stored beyond the closing time of any course (or, say mid-night for 24 hour courses if any).  This means that unlike the course data, you don't need to persist round data to storage.  However when running low on RAM the garbage collector should be able to reclaim Round objects that have been completed.

    After a player has swiped their card the card-swipe station will lookup the player's Round obect.  Then it will invoke some methods on the Round object:

    • int currentScore ()
      to display the user's score so far (this is the number of strokes above or below par, for the holes played so far)
    • int numberOfHolesPlayed ()
      Returns the number of completed holes in this round;
    • void enterScore(int strokes)
      to enter a the score for the next hole.  (Note the current design doesn't allow a player to skip holes, they must be played in order);
    • int[] scoreDetail()
      returns the array of strokes per hole.  This method gets called by the final hole swipe-station, to print out the players scorecard (which has pre-printed coupons on the reverse side.)  After this method is invoked the round object can be disposed of.
  2. Class Course

    Class Course holds information about a particular mini-golf course:  the course name and address info, and the par (number of strokes an average-good player would need) for each hole in that course.  Course objects are basically just simple data records.  They should be immutable.  They will need the following methods:

    • String getName ()
    • int getNumberOfHoles ()
    • int parForHole ( int hole )
  3. Class Main

    Class Main will need a number of public static methods.  These get invoked by the card-swipe stations (actually their objects, which run in a separate thread each) when a new round is created, when a user swipes their card, and when a user enters a score.  The methods needed include:

    • static void newRound ( String courseName, String playerName )
      This method creates and stores a new round object.
    • static Round getRound (String player, String courseName )
      This method looks up the Round object.  Note it isn't specified how you store Round objects, but a likely choice is some sort of Collection.  Keep in mind the garbage collection requirements for this object, discussed above.
    • static Course getCourse ( String courseName )
      Returns a Course object.  These must be persisted to storage but there aren't many courses so creating a Collection to hold them all is reasonable.  However exactly how you do this is an implementation detail.
    • static int scoreSoFar( String courseName, String playerName )
      This method looks up the round information and returns it's score so far to the swipe station, to display.  (Yes it is redundant with Round.currentScore(), but the customer insisted — probably has a nephew or niece who is a computer expert.)
    • static enterStrokes ( String courseName, String playerName, int strokes )
      This method is also redundant.  It also will be used by the swipe-station once a player hits the button for their number of strokes for that hole.

    In addition class Main needs a main method.  This method could read the course data from storage and create all the course objects.  It should do any other initialization required (e.g., create the collection object used to hold Round objects).

    In version 1 the course information is stored in a text file.  It is the job of the Main.main method to create the Course objects from the data records in the data file.  The file can be either text or XML and the file format is up to you.  (The format specification must be included with your project submission!)

Other Classes

A CardSwipeStation class that interfaces with the card-swipe station hardware is provided by an out-source vendor and will be available when needed.  This class will detect card-swipe events and keypad data entry, and will invoke the various public methods of the two classes above (Round and Main) as needed.

The card-swipe station for the last hole on a course includes a printer.  Once the score for this hole is entered, the player's score-card is printed and the round is complete.

Since we don't have the required hardware we can simulate the card-swipe class.  (A GUI to act as the card-swipe stations would be a nice touch but is not required.)

Potential Changes (Requirements not part of the provided RFP)

  1. Allow players to play holes out of order (assume the CardSwipeStation class knows which card-swipe station (i.e., the hole number) was used to enter a score.  (Players must still play the final hole last; in addition to printing their score-card it swallows their golf ball.)
  2. Plan for a version 2 where course information is stored in a database instead of a file.
  3. Enhance the application to allow two players with the same name to play the same course simultaneously, or for two courses to have the same name.
  4. Enhance the application to support a frequent golfer feature, where a player can sign up and have the system remember their rounds (and the date they played them).  This feature could also support tournament play.

Team Assignments

Team A will implement class Round and add any implementation methods or classes needed.  You will also create the black-box JUnit tests for class Course and class Main.

Team B will implement class Course and class Main, and add any implementation methods or classes needed.  You will also create the black-box JUnit tests for class Round.

Note!  It is not expected for either team to completly implement the classes (although you certainly can if you wish).  You will need a skeleton with stub methods, so the other team can run the JUnit tests.  You should implement one of the design requirements, so not all JUnit tests will fail.  But you don't have time to implement them all.