HW3: Battleminton¶
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.
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.
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:
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:
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):
- A
.zip
file (namedhw3.zip
) that contains the directory/folderhw3
at the top level. It must include your implementation of the source code forBattle
,ShuttlecockPart
,BodyPart
, andBattlemintonEvent
.
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.
Recommended Process¶
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¶
- Read and understand the entire assignment.
- Create a directory/folder for this assignment named
hw3
(under thesrc
directory/folder). - Download
BattlemintonTest.java
to a directory outside of your VSCode directory.
Understand the Test Cases¶
- Read and understand the test cases in
BattlemintonTest.java
. - By hand (i.e., using pencil and paper), calculate the expected output
from
BattlemintonTest.java
.
Write the Simple enums¶
- Write
ShuttlecockParts.java
. - Write
BodyParts.java
.
Stub-Out the Remaining Components¶
- Create a stub for the
BattlemintonEvent
enum that includes all of the attributes and methods with "javadoc" comments. - 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¶
- Outside of VSCode, copy
BattlemintonTest.java
intohw3
.
Write the Remaining enum and Class¶
- Write and test
BattlemintonEvent.java
one method at a time. - 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.
- What syntax error is generated in
BattlemintonEvent
if you type aBodyPart
incorrectly? - If you used
String
literals instead of an enum, what syntax error would be generated if you were to type one of them incorrectly? - 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? - How would you invoke the
isScoringContact()
method forBattlemintonEvent.JET
(for example)? - Could you invoke the
isScoringContact()
method on theString
literal"JET"
if, for example, you had usedString
literals instead of an enum? - 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?