Skip to content

HW3: Battleminton

Battleminton Logo

Learning Objectives

This homework assignment is designed to help you understand the differences between enums and classes in Java.

Overview

Several student members of JMU's PlayMU have used what they have learned from playing board games and video games to create an exciting new sport, Battleminton. Thus far they have been quite successful in getting people to support their cause, however they know that there are several services that they must provide in order to become a successful professional sport. So, they have come to you to start writing some of the software they need.

Specifically, they want you to write a Battle component that encapsulates a battle involving two players, a BattlemintonEvent component that encapsulates the three different kinds of Battleminton events, a BodyPart component that encapsulate the parts of the body that are relevant in Battleminton events, and a ShuttlecockPart component that encapsulates the different parts of a shuttlecock.

Existing Classes

They have provided you with a main class that might help you get started with testing.

BattlemintonTest.java

The Components to be Written

You must write three enumerated types, one that is very simple and has no attributes or methods, one that is fairly simple and has only an accessor, and one that is more complicated. You also must write one "normal" class. The relationships between these different components are illustrated in the following UML class diagram. As in the past, the package has been omitted from this diagram.

Class Diagram

Your implementation must conform to the specifications in this diagram as well as the specifications listed below. You must use arrays – you must not use List, ArrayList etc.

ShuttlecockPart

Shuttlecocks have two principle parts, as illustrated below:

Shuttlecock Parts

BodyPart

As you (hopefully) already know, the human body has many different parts. The parts that are relevant for Battleminton are the arms, hands, head, feet, legs, and torso. The points awarded for a hit on a particular body part varies with the body part, as illustrated below:

Body Parts

To think about… Include the following body parts: Arms (6 points), Fingers (2 points), Head (10 points), Knees (4 points), Torso (9 points).

BattlemintonEvent

There are three different Battleminton events (named for the maximum speed of the shuttlecock that is used in each): glider, propeller, and jet. In addition to the speed of the shuttlecock used during the event, the different events vary in: the parts of the shuttlecock that can be used to score a point, and the parts of the body that can be used to score a point. The attributes in BattlemintonEvent are used to keep track of these differences as follows:

Event Shuttlecock Speed Shuttlecock Parts Body Parts
Glider 30 mph Base, Feathers Arms, Head, Torso
Propeller 90 mph Base All
Jet 120 mph Base Head, Torso

The Explicit Value Constructor

The explicit value constructor in BattlemintonEvent has parameters that can be used to initialize the attributes. The speed parameter obviously contains the maximum speed of the shuttlecock. The feathersOK parameter will contain true when the feathers can be used to score a point (and, hence, the shuttlecockParts attribute will need to contain two elements) and will contain false when only the base can be used to score points (and, hence, the shuttlecockParts attribute will need to contain one element). The targets parameter is variable length (as indicated by the ... after the type) and will hold the (appropriately sized) array of BodyPart objects that can be scored on. To think about… The speed is 50 for all instances.

When invoking this constructor, the actual parameters must include an int and a boolean and may contain 0 or more BodyPart objects (separated by commas). Internal to this constructor, the formal parameter named targets will be a BodyPart[] that will contain 0 or more elements (corresponding to the BodyPart objects in the actual parameters). For example, this constructor might be invoked in BattlemintonEvent as follows:

JET(120, false, BodyPart.HEAD, BodyPart.TORSO)

and might be partially implemented as follows:

private BattlemintonEvent(int speed, boolean feathersOK, BodyPart... targets) {
  this.speed = speed;
  this.targets = targets;
  // Construct and initialize an appropriately-sized shuttlecockParts array
}

The Methods

The isOnTarget() method must return true when the parameter can be scored on in the owning BattlemintonEvent and must return false otherwise. To think about… Make this method return true when the parameter is not null.

The isScoringShuttlecockPart() method must return true when a contact of the given parameter can be used to score points in the owning BattlemintonEvent. To think about… Make this method return true when the parameter is not null.

The isScoringContact() method must return true when a contact of the given ShuttlecockPart on the given BodyPart scores points in this BattlemintonEvent, and must return false otherwise. This method must not duplicate code in any other methods. (It can, of course, invoke other methods.)

The points() method must return the number of possible points associated with the given BodyPart when a contact of the given ShuttlecockPart on the given BodyPart scores points in the owning BattlemintonEvent, and must return 0 otherwise. This method must not duplicate code in any other methods. (It can, of course, invoke other methods.)

Battle

A Battle involves two players (designated as the west player and the east player) competing in a specific BattlemintonEvent.

The explicit value constructor in Battle must initialize all of the attributes in the obvious way, and the accessors in Battle must return the associated attributes.

The increaseWestScore() and increasEastScore() methods must increase the value of the associated attributes by the points scored when there is a contact of the given ShuttlecockPart on the given BodyPart. This method must not duplicate code in any of the other enums or classes. (It can, of course, invoke other methods.)

The toString() method must return a String representation of the playerWest, scoreWest, playerEast, and scoreEast attributes (in that order) formatted using "%s %s, %s %s" as the format String. To think about… Terminate the return String with a tab character.

Submission

You must submit (using Gradescope):

  1. A .zip file (named hw3.zip) that contains the directory/folder hw3 at the top level. It must include your implementation of the source code for Battle, ShuttlecockPart, BodyPart, and BattlemintonEvent.

There is no limit on the number of submissions and no penalty for excessive submissions. Note that your submission will not be graded if it does not comply with the specifications. So, your submission should include a stubbed-out version of all of the classes. (This will allow you to get credit for the classes/methods that you do implement correctly.)

Grading

Your code will first be graded by Gradescope and then by the Professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment

Gradescope Grading

Your code must compile (in Gradescope, this will be indicated in the section on "Does your code compile?") and all component names and method signatures must comply with the specifications (in Gradescope, this will be indicated in the section on "Do your class names, method signatures, etc. comply with the specifications?") for you to receive any points on this assignment. Gradescope will then grade your submission as follows:

Criterion Points Details
Conformance to the Style Guide 20 points (All or Nothing; Success Required)
Correctness 80 points (Partial Credit Possible)

Gradescope will provide you with hints, but may not completely identify the defects in your submission.

Note that some of the criteria are described as "Success Required". This means that Gradescope will not assess subsequent criteria unless this criterion is satisfied (and you will receive a grade of 0 for the criteria that aren't assessed). So, for this assignment, if your code does not conform to the style guide then nothing else will be assessed (and you will receive a grade of 0 for the assignment). You should, at this point, be able to use the tools on your computer to comply with the style guide, without assistance from Gradescope.

Manual Grading

After the due date, the Professor may manually review your code. At this time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc.

Since nobody will be looking over your shoulder, you can use any process that you would like to use. However, it is strongly recommended that you use the process described here.

Get Started

  1. Read and understand the entire assignment.
  2. Create a directory/folder for this assignment named hw3 (under the src directory/folder).
  3. Download BattlemintonTest.java to a directory outside of your VSCode directory.

Understand the Test Cases

  1. Read and understand the test cases in BattlemintonTest.java.
  2. By hand (i.e., using pencil and paper), calculate the expected output from BattlemintonTest.java.

Write the Simple enums

  1. Write ShuttlecockParts.java.
  2. Write BodyParts.java.

Stub-Out the Remaining Components

  1. Create a stub for the BattlemintonEvent enum that includes all of the attributes and methods with "javadoc" comments.
  2. Create a stub for the Battle class that includes all of the attributes and methods with "javadoc" comments.

Add the Provided Classes to the Project

  1. Outside of VSCode, copy BattlemintonTest.java into hw3.

Write the Remaining enum and Class

  1. Write and test BattlemintonEvent.java one method at a time.
  2. Write and test Battle.java one method at a time.

Relevant Programming Patterns

An understanding of the following programming patterns will help you complete this assignment:

Questions to Think About

You don't have to submit your answers to these questions, but you should try to answer them because they will help you determine whether or not you understand some of the important concepts covered in this assignment.

  1. What syntax error is generated in BattlemintonEvent if you type a BodyPart incorrectly?
  2. If you used String literals instead of an enum, what syntax error would be generated if you were to type one of them incorrectly?
  3. Taking your answers to the previous two questions into consideration, what is one of the big advantages of using an enum rather than a collection of String literals?
  4. How would you invoke the isScoringContact() method for BattlemintonEvent.JET (for example)?
  5. Could you invoke the isScoringContact() method on the String literal "JET" if, for example, you had used String literals instead of an enum?
  6. Taking your answers to the previous two questions into consideration, what is another big advantage of using an enum rather than a collection of String literals?