Assignment 4: All In a Row, Part 3: Different Models
Due dates:
Implementation: Wednesday, Feb 19 at 8:59pm
Self-evaluation: Released Thursday, Feb 20 at 9:05pm, Due Friday, Feb 21 at 11:59pm
Note: Homeworks 5 through 8 will begin a new project, and you will be
working with a partner for them. Start thinking about who you’d like to
partner with. You will sign up with your partner on the handin server, and you
will not be able to submit subsequent assignments until you are part of a team
on the handin server. If you do not know (or remember) how to request teams,
follow
these
instructions. Please request teams no later than the start of homework 5,
which is Feb 20 —
1 Purpose
The benefits of the model-view-controller architecture shine when we need to add new features, by isolating relevant parts of our design and changing them independently. In this assignment we will see those benefits pay off by supporting other forms of Poker Polygons. The goal of this assignment is to give you a chance to critically examine your earlier design choices, and either leverage or revise them to enable adding variations of this game with minimal change and duplication of code.
With one exception (main), all new classes and interfaces for this
homework should be in the cs3500.pokerpolygons.model.hw04
package. All classes written in previous assignments, even if improved upon,
should remain in their respective packages.
There will be two submissions for this assignment:
Your actual implementation and full test suite
A self-evaluation, due one day plus one hour later than the late deadline of the actual implementation, where we will ask you to reflect on your implementation and testing choices.
The same late-day policy as on the previous homework applies: each of these two submissions independently may use up to one late day, and you are still able to submit your self-evaluation on time even if you submit your implementation late.
You are expected to use your code from the previous assignment as the starting
point for this assignment. However, please ensure all of your new model related code is
in the cs3500.pokerpolygons.model.hw04
package. Your new view must be in the
cs3500.pokerpolygons.view
package. Additionally, your code from
the previous assignment should remain in the cs3500.pokerpolygons.model.hw02
,
cs3500.pokerpolygons.view
and cs3500.pokerpolygons.controller
packages.
2 Poker Rectangles
The traditional game of Poker Polygons is played on a square board, not a triangle. For this model, you will be getting closer to that origin by playing the game on a rectangular board. The sides of the board must each be greater than or equal to 5 cards. Note that because this is a rectangle, the sides need not be equal.
Scoring changes slightly in this version. In Poker Rectangles, you only score the
columns and rows with 5 or more cards. This means diagonals are not scored.
Implement this model as a class called PokerRectangles
which again uses your
cards.
This version has only the following two constructors
public PokerRectangles(int width, int height)
which initializes the model with a newRandom
object for random operations. It should throw anIllegalArgumentException
if width or height are strictly less than 5.public PokerRectangles(int width, int height, Random rand)
which initializes the model with the givenRandom
object for random operations. It should throw anIllegalArgumentException
if width or height are strictly less than 5 or if the random object is null.
However, with the new board comes a new view. Since the PokerTrianglesTextualView
assumed we wanted to view the model’s board as a triangle, we need a new view that
assumes we want to view the model’s board as a rectangle. We shall call that view
PokerRectanglesTextualView
.
It should implement the PokerPolygonsTextualView
with the only difference being
the view assumes the polygon is a rectangle. This means the field is still of type
PokerPolygons<?>
.
Note: It is okay if you rewrite the existing PokerTrianglesTexView
to
properly handle any shape, but you still need to define the new class and have that new class do
the same without duplicating existing code.
3 Looser Poker Triangles
In the original version of Poker Triangles, a flush was defined as a poker hand of 5 cards where every card has the same suit. Furthermore, a straight was defined as a hand of 5 cards such that if sorted, form a run: a sequence of ranks that can be ordered such that the numerical value of each card’s rank increases by 1.
However, we can loosen these rules. For this new version of PokerTriangles, we will redefine both of those terms as follows
Flush: The hand has 5 cards, all of which have the same color. Of note, diamonds and hearts have the same color of red. Clubs and spades have the same color of black. Here are some examples of flushes:
3♣,8♣,5♣,6♣,7♣: Still a flush because if you have the same suit, you have the same colors.
3♣,8♣,5♠,6♣,7♣: Notice the 5 is a spade, not a club. But since all the suits are black, this is now a flush.
4♢,9♢,2♡,8♢,6♡
10♡,3♡,K♡,2♢,A♡
Straight: The hand has 5 cards and those cards, if sorted, form a skipped run: a sequence of ranks that can be ordered such that the numerical value of each card’s rank increases by 1 or 2.
3♣,4♡,5♢,6♠,7♡: The next numerical value is always one more than the previous numerical value, making this a run.
4♠,5♢,2♠,3♡,6♢: Still a straight because when sorted, it fits the definition.
8♣,9♣,10♠,J♡,K♢: J has a numerical value of 11 and K a numerical value of 13. Notice that when sorted, the next rank in the sequence increases by either 1 or 2.
A♣,3♠,4♣,5♢,6♡: A can have the numerical value of 1, which allows this straight to be formed.
9♡,J♡,K♠,Q♠,A♡: A can also be the highest numerical value of 14, which allows this straight to be formed.
2♡,4♡,6♠,8♠,10♡: Multiple cards are allowed to go up by 2 in rank, resulting in this straight.
It is worth noting that straights still cannot wrap around (e.g. K♠,Q♠,A♠,2♠,3♠) because then the sequence of ranks is not always increasing by 1 or 2.
This does have an effect on the definition of a straight flush.
Straight Flush: The hand has 5 cards has the same color and those 5 cards, if sorted, a skipped run: a sequence of ranks that can be ordered such that the numerical value of each card’s rank increases by 1 or 2. Of note, diamonds and hearts have the same color of red. Clubs and spades have the same color of black.
Here are some examples of straight flushes:
3♣,4♣,5♣,6♣,7♣: The next rank is always one more than the previous rank, making this a run.
4♣,5♣,2♣,3♣,6♣: Still a straight because when sorted, it fits the definition.
10♠,J♠,K♠,Q♠,A♠: A can also be the highest numerical value of 14, which allows this straight to be formed.
8♠,9♠,10♠,J♠,K♠: J has a numerical value of 11 and K a numerical value of 13. So while Q is skipped, this is still a straight flush.
A♢,2♢,4♡,6♢,7♢: This is still a straight as 2 and 4 only differ by two and also 4 and 6 only differ by 2. Also all of the suits are red, so it is a flush as well.
3♠,5♠,7♠,J♠,9♣: Every rank, when sorted, increases by 2, resulting in a straight. Also, all the suits are black, so it is a flush as well.
It is worth noting that straights cannot wrap around (e.g. K♠,Q♠,A♠,2♠,3♠) because then the sequence of ranks is not always increasing by 1 or 2.
Implement this new model as a class called LoosePokerTriangles
which again uses your cards.
Of note, this model must work with the existing PokerTrianglesTextualView
as this board
is a triangular shape.
4 Assignment Requirements and Design Constraints
Design classes implementing the
PokerRectangles
andLoosePokerTriangles
variants of PokerPolygons as well as thePokerRectanglesTextualView
. Both variant model classes should clearly implementPokerPolygons
, and clearly share some commonalities with the existingPokerTriangles
. In your implementation, strive to avoid as much code-duplication as possible among the three models, while making sure that all three fully work properly. If done correctly, none of your code from before should break or be affected. You may need to refactor your earlier code, though, to make it more flexible and enable better code reuse for these new classes.Design a builder class, named
PokerPolygonsBuilder
, as described below.Implement a
main
method to allow you to choose different game variants from the command line, when running your program. (This is described below.)If you had to change any part of your design from prior assignments, document those changes in a README file. (This must be a plain-text file.)
Test everything thoroughly: make sure the new models work properly, and that the controller can control them as well as it could the original model. You do not need to test your
main
method.
You must complete these requirements while respecting the following constraints:
You are not allowed to change the interface of the model (
PokerPolygons
) at all from before.You are not allowed to change the controller interface (
PokerPolygonsController
) at all from before.As before, you are not allowed to add any additional public methods in your classes, with the exception of any expected constructors.
You must create separate model implementations, without eliminating
PokerTriangles
from before. That is, models that represent all variations of the game must co-exist.
In this assignment it is important not only to have a correctly working model, but also a design that uses interfaces and classes appropriately. Make sure you minimize replication of code. You may refactor your earlier designs to do this. You may also have to change earlier implementations to remove bugs. This is OK, but must be properly documented and justified.
5 Hints
You should always plan out things in detail before you code. But this assignment is designed to be significantly more difficult if you jump into the code prematurely and try to figure out things as you code!
For each variant, go through each operation of the model interface, and think about how that operation works for this variant of the game. Planning out every operation before coding will save you a lot of time!
Recall that your view needs to be able to work with any model implementation, without knowing which one!
You may be tempted to discover all possible abstractions beforehand. Make sure you minimize code repetition, but not over-abstract so much that some methods lose meaning. Even private helper methods should have a specific purpose! While it is good to anticipate abstraction, there is nothing wrong with thinking about abstraction after implementing all the code. It’s the end result that counts!
6 The PokerPolygonsBuilder
class
Updates are marked in red.
Design a class with the above name in the cs3500.pokerpolygons.model.hw04
package. The class should define a
public enum GameType
with three possible values: TRI
,
RECT
and LOOSE
.
The class should offer the following methods
public PokerPolygonsBuilder setType(GameType type)
that sets the type of the game to the given type.public PokerPolygonsBuilder setSideLength(int sideLength)
that sets the side length of a Poker Triangles game to the given length.public PokerPolygonsBuilder setWidth(int width)
that sets the width of the Poker Rectangles game to be built to the given width.public PokerPolygonsBuilder setHeight(int height)
that sets the height of the Poker Rectangles game to be built to the given height.public PokerPolygons<X> build()
where X is your card type that returns an instance of (an appropriate subclass of)PokerPolygons
, depending on the customizations made.
It should also offer the following constructor
public PokerPolygonsBuilder()
which sets the customization options to the defaults mentioned for themain
method further below.
You may add additional methods to your PokerPolygonsBuilder
class, but
you must maintain the build
and customization methods specified above, for our tests to
compile against your code.
7 The main()
method
Add the following class to your project:
package cs3500.pokerpolygons;
public final class PokerPolygonsGame {
public static void main(String[] args) {
// FILL IN HERE
}
}
This main()
method will be the entry point for your program. Your
program needs to take inputs as command-line arguments (available in your
program through the argument args
above). Review the
documentation
for command-line arguments in a Java program.
Specifically:
Updates are indicated in red.
The first command-line argument must be a string, specifically one of
tri
,loose
, orrectangle
. This argument will decide which game variant (and hence which model and view) you should use. If this argument is missing or incorrect, the program should throw anIllegalArgumentException
.YouThe user may optionally pass two more argumentsH
andL
, both of which should be parsed as integers, where H specifies the number of cards in the starting hand, and L specifies the side length of the board. If unspecified, you should use a hand with a single card and a side length of 5 as the defaults. If the variant is the rectangle variant, then L represents the number of columns (i.e. length) and there can be a third optional argumentW
representing the number of rows (i.e. width). The defaults forL
andW
are both 5.
The following are some examples of valid command lines, and their meanings:
tri
produces a basic game of Poker Triangles with default hand size and default board size. A Poker Triangles view is also created for this game.tri 1 5
achieves the same thing, but explicitly sets the size of the game.rectangle 3 10 7
produces a game of Poker Rectangles with a hand size of 3 and a board with 10 columns and 7 rows. A Poker Rectangles view is also created for this game.loose 8
produces a game of loose Poker Triangles with a hand size of 8 and the default board size. A Poker Triangles view is also created for this game.loose 8 7
produces a game of loose Poker Triangles with a hand size of 8 and a board with a side length of 7. A Poker Triangles view is also created for this game.
Hint: Notice that the options for a model have defaults and are customizable. Consider having an object that represents the options. If so, how can we handle the sheer customizability of these options?
This command-line specification also does not allow for customizing the deck of cards to be dealt. It is an interesting challenge to think how you might design such configuration options.
This is not an exhaustive list; other command lines are possible.
When you specify command-line arguments, they are always treated as strings, even if they are not within quotes. However, quotes are necessary if you want to pass a string that contains spaces in it.
These arguments will appear in the String[] args
parameter to your
main
method; you can use them however you need to, to configure your
models. For this assignment, you do not need to explicitly handle
invalid command lines for the optional arguments
(e.g. by producing an informative error message).
However, your code should not crash (e.g. by specifying -1 as the hand size
, and causing an IndexOutOfBounds
exception).
7.1 To actually run your program with command line arguments in IntelliJ IDEA:
Go to
Run > Edit configurations
Click the
+
button in the upper left, and selectApplication
from the dropdown that appears.Give the new configuration a name that you’ll remember (e.g. "Basic 7/3").
In the
Main class
textbox, entercs3500.pokerpolygons.PokerPolygonsGame
– the fully-qualified name of the class with yourmain
method.In the
Program arguments
textbox, enter the command line arguments you want to use for this configuration, e.g.tri 1 5
Leave everything else at their defaults, and click Ok.
You can repeat this process as many times as you want, to make as many run configurations as you need. Then to choose among them, use the dropdown menu next to the run icon in the toolbar:
and press Run.
8 What to submit
For your implementation: submit a properly-structured zip containing
All your code from before (with as few changes to the classes as possible, and any changes fully explained in comments)
Your implementations of Poker Rectangles and Loose Poker Triangles, and any support classes needed
Your
PokerPolygonsGame
class with themain()
method.Tests for all models in one or more JUnit test classes. It is a good idea to include your earlier tests as well, for regression testing. We certainly will...
Your README file documenting your changes.
Your main class should be in the cs3500.pokerpolygons
package,
your new view in the cs3500.pokerpolygons.view
package,
while all other new
classes and interfaces for this homework should be in the
cs3500.pokerpolygons.model.hw04
package. All classes written in previous
assignments, even if improved upon, should remain in their respective
packages.
As with Assignment 3, please submit a zip containing only the src/
and
test/
directories with no surrounding directories, so that the
autograder recognizes your package structure. Please do not include your
output/
or .idea/
directories —
9 Grading standards
For this assignment, you will be graded on
Whether you had to modify any previously written interfaces,
whether your code implements the specifications (functional correctness),
how well your code is structured to avoid duplication, improve readability, etc.
the clarity of your code,
the comprehensiveness of your test coverage, and
how well you follow the style guide.
Please submit your homework to https://handins.ccs.neu.edu/ by the above deadline. Then be sure to complete your self evaluation by its deadline.