With the anticipated success of Forneymon (expected to hit stores after a tiny court-battle with Nintendo/Game Freak), the executives of Forney Industries have tasked you with creating a companion virtual card-game.
Towards this end, your boss has given you the following specifications to design the Forneymon card classes, which are going to find initial market penetration in the form of a memory game where cards are initially face-down and then flipped as players try to match them (just to get the brand out).
Debug
Important: Make sure to read the entire problem statement before writing any code!
GitHub Classroom + Skeleton
Definition
Start with the solution skeleton in-hand! The following will also serve as your submission mechanism (see submission instructions below).
Assignment
Advanced Style Guide
Definition
The Java Style Guide has expanded! (will it ever stop?!) Take a look at the new entries as they pertain to this assignment — don’t lose credit!
Assignment
Specifications
Design a class called ForneymonCard that adheres to the following specifications.
-
Every ForneymonCard pertains to a
Forneymonobject from the lecture (e.g., Burnymon and Dampymon), which should be stored in a field with the proper access restriction (in other words, ForneymonCards have a Forneymon attached to them, but are not Forneymon objects themselves). -
ForneymonCards can be created via one of two constructors:
Toolkit
It’s perfectly fine to define multiple constructors for a class, as long as those constructors do not share the same parameterizations.
ForneymonCard (Forneymon forneymon), a parameterized constructor, which expects a reference to a Forneymon object that the card will represent. If the Forneymon argument is null, throw anIllegalArgumentException.ForneymonCard (), the default constructor (i.e., the constructor with no parameters), which represents (by arbitrary default), a ForneymonCard of a Burnymon named “MissingNu”.
-
You will also implement two simple “getter” methods:
getName(), which returns the name of the Forneymon the card represents.getType(), which returns the type of the Forneymon the card represents (e.g., “Burnymon”; Hint: some Object methods from the lecture might be useful here).
-
When printed out (i.e., for toString()), a ForneymonCard shall return a String of the format: “Type: Name”. E.g., a Burnymon named Burny would return: “Burnymon: Burny”
-
ForneymonCards should be comparable via
equalsby the same criteria that the Forneymon that they represent are compared. This means you should also override a ForneymonCard’shashCodeto be the same as the Forneymon it represents.
Design a class called FlippingForneymonCard that adheres to the following specifications.
- FlippingForneymonCards are ForneymonCards (share properties and methods) except that they may be placed face-up or face-down. You shall implement this property as a boolean field that is false when face-up and true when face-down.
- FlippingForneymonCards can be created via one of two constructors:
FlippingForneymonCard (Forneymon forneymon, boolean faceDown), a parameterized constructor, which expects a reference to a Forneymon object that the card will represent and whether or not the card is face-down. If the Forneymon argument is null, throw anIllegalArgumentException.FlippingForneymonCard (), the default constructor which represents (by arbitrary default), a ForneymonCard of a Burnymon named “MissingNu” that starts face-down.
public boolean flip ();Each FlippingForneymonCard canflip();which makes it face-up if it was previously face-down, and vice versa. Return whether or not the card is face up after flipping it (i.e., return false when face-up and true when face-down).- Define a method
int match (FlippingForneymonCard other);that returns:- 2 if either this or the other FlippingForneymonCard are face-down.
- 1 if both are face-up and
equal. - 0 if both are face-up and disagree on either their name or the Forneymon type.
- A FlippingForneymonCard that is currently face-down will instead return the string ”?: ?” when toString() is called on it, else, it will use the ForneymonCard’s toString behavior when face-up.
- A FlippingForneymonCard
equalsanother FlippingForneymonCard by the same rules of equivalence as ForneymonCards (i.e., you don’t need to override it in this subclass).
Here is a snippet from the attached unit tests to see how the above is meant to function:
...
@Test
public void flippingTest_t0() {
// Create three different Burnymon objects, 2 of which share a name
Burnymon b1 = new Burnymon("Burny"),
b2 = new Burnymon("Burny"),
b3 = new Burnymon("Scald");
// For each of these, create a new card representing it (all face up to start)
FlippingForneymonCard f1 = new FlippingForneymonCard(b1, false),
f2 = new FlippingForneymonCard(b2, false),
f3 = new FlippingForneymonCard(b3, false);
assertEquals("Burnymon: Burny", f1.toString());
assertEquals(1, f1.match(f2));
assertEquals(0, f1.match(f3));
assertTrue(f1.equals(f2));
assertFalse(f1.equals(f3));
// f1 is now face-down
f1.flip();
assertEquals("?: ?", f1.toString());
assertEquals(2, f1.match(f2));
assertEquals(2, f1.match(f3));
assertTrue(f1.equals(f2));
assertFalse(f1.equals(f3));
}
...Notes
Here’s the proper order of operations:
- Clone the Classroom repository with the solution skeleton.
- Add the JUnit library to the classpath, per usual, using the method described in the Git / IntelliJ tutorial below.
- Note that the provided
ForneymonCardTests.javawill all fail out-of-the-box because all methodsthrow new UnsupportedOperationException();. This is a standard exception to throw in Java when you need to specify a method signature, but haven’t yet defined its implementation. Doing so allows your code to compile, while also letting you focus on writing one method at a time to develop and test incrementally. - Decide what fields and inheritance structure you’d like each of ForneymonCard and FlippingForneymonCard to have.
- Choose the fields and complete the constructors of each Card class — remember your clean coding habits!
- Complete the methods specified above (including the requested overridden methods).
Other notes, hints, and warnings:
-
Consider which properties and behaviors between the two cards are “general” vs. “specialized” in constructing your inheritance structure.
-
Ignore the edge case of two separate cards representing the same Forneymon object — we’ll consider this undefined behavior.
-
Neither of these classes need be
abstract; we’ll assume both the basic ForneymonCards and their Flipping variants are both instantiable. -
Test your implementations by running the given unit tests, and add some others that may test “blind spots” in your code!
Debug
Once more, I’m only giving you some of the grading unit tests.
Make sure your solution works for the edge cases AND for other Forneymon species that are perhaps not part of the skeleton!
Submission
Definition
You will be submitting your assignments through GitHub Classroom!
What
Complete all classes that accomplishes the specification above, in the project structure given in the skeleton above.
How
To clone this assignment (if you need a refresher), consult the guide here:
Assignment
To submit this assignment:
- Simply push your final, submission copy to the GitHub Classroom repository associated with you or your group.
- If you worked in a group (3 individuals maximum), ensure that your GitHub Classroom group includes all members, and place all group members’ names at the top of all submitted files (in appropriate
JavaDoc commenting fashion) AND in the accompanying
readmefile.