Assignment 2: All In a Row, Part 1:   The Model
1 Purpose
2 Poker Polygon Game
2.1 Context
2.1.1 Cards for the Game
2.2 Flow of the game
2.2.1 Poker Hands
2.3 Scoring with the Triangular Polygon
3 Building Poker Triangles
3.1 Cards
3.2 Expected operations
3.3 Your Model Implementation
3.4 Viewing the model
3.5 Testing
4 Package Management
5 What to submit
6 Grading Standards
7 Submission
8.9

Assignment 2: All In a Row, Part 1: The Model

Due dates:

Starter files: code.zip

Note: The description may make assignments seem longer than they are. Distilling the description to make a list of all the things you are actually supposed to do will go a long way in having a good plan to tackle it. Read the description several times to confirm this list before acting on it!

1 Purpose

The primary goal of this assignment is to practice implementing an interface based on given specifications, and by choosing an appropriate data representation that helps in providing the functionality promised by the interface.

Please ensure all of your source code is in the cs3500.pokerpolygons.model.hw02 and cs3500.pokerpolygons.view packages. Note that the model package refers to hw02, and the view does not. (See Package Management below.)

There will be two submissions for this assignment:

A reminder about late days: Each submission is a distinct submission, and each one will independently use up your late days if you submit after the deadline. (Submitting late for the implementation does not mean you automatically get a “free” late day for the self-eval as well – submitting both parts late will use two late days.) The 24-hour delay for the self-evaluation is deliberate, so that even if you submit your assignment late, you can still submit your self-evaluation on time.

Read below for more details of each submission.

2 Poker Polygon Game

2.1 Context

In the next three assignments, you will implement the common single-player card game called “Poker Polygon”, a more general version of the older game “Poker Squares”. You can play the game of Poker Squares here to get a sense of the game in its most basic form.

In the first two assignments, you will focus on implementing “Poker Triangles” where the polygon to fill with cards is right-angle equilateral triangle. The image above shows a Poker Triangle layout at the start of a game.

2.1.1 Cards for the Game

Poker Triangles uses the standard suit-rank playing cards for its game. There are four suits: clubs (), diamonds (), hearts (), and spades (). Hearts and diamonds are colored red; clubs and spades are colored black.1In the textual representation here, “red” suits are simply shown as hollow shapes, while “black” suits are filled-in. There are thirteen ranks: ace (written A), two through ten (written 2 through 10), jack (J), queen (Q) and king (K). Note that two cards are the same if they have the same suit and rank.

In the game itself, the rank of a card is associated with a numerical value. The ranks two through ten have the numerical values 2 through 10 respectively. Jacks have a numerical value of 11, Queens a numerical value of 12, and Kings a numerical value of 13. Aces are special in that their numerical value can either be 1 or 14 depending on the poker hand. 2For those versed in poker, aces are both high and low in this game. These numerical values will come into play when determining the score of the game.

There are two areas of the game play. First, there is the board itself, a right-angle equilateral triangle of empty positions. The triangle can have any side length greater than or equal to five cards. Then there is the hand itself, a collection of cards the player can choose from to fill the empty positions on the board.

In a standard game, there are 52 cards: one complete set of all possible ranks in each possible suit. Our game will be more flexible to accommodate the arbitrary size of the board: it will allow for any deck of cards, which may have duplicate cards, as long as there are at least enough cards to fill the polygon and the starting hand. Furthermore, the size of the hand can be any positive size less than or equal to the number of cards needed to fill the triangle at the start of the game greater than zero.

As an example, suppose we are working with a board where the triangle side’s length is 5 cards. Then the following decks are valid for starting the game:

2.2 Flow of the game

Play starts by dealing a full hand to the player and an empty polygon. The hands are drawn from the top of the deck, one after the other.

A player must make one of two moves:

The player continues to make their moves until the game is over. The game is over when the board has no empty positions left. In other words, the player has filled each position on the board with a card.

The score of the game is determined by the poker hands developed along the internal rows, columns, and outer sides of the triangle that have 5 or more cards.

2.2.1 Poker Hands

Before we can describe scoring, we must first describe the types of poker hands that will be used in scoring. We list the poker hands in the order they are evaluated. In other words, if the hand is not a straight flush, then we see if the hand is a four of a kind. This continues until we reach high card, which every hand satisfies the definition for.

2.3 Scoring with the Triangular Polygon

To determine the score of a Poker Triangles game, the player must look at the sides of the triangle and any row or column that has 5 or more cards. (Recall that the side length must be at greater than or equal to 5, so the sides of the triangle are guaranteed to have 5 or more cards). Of note, the same card can be used in multiple different types of hands. In other words, even if a card helps make up the best poker hand for one row, column, or diagonal, it does not prevent that card from being used in another row, column, or diagonal’s best poker hand.

Consider the following triangle with a side length of 7.

2♢
3♠  8♢
4♡  3♡  5♢
5♣  4♣ 10♢  3♣
6♠  8♠  5♡  9♡  7♡
K♣  9♢  J♡  6♣  K♠  J♢
Q♠  J♠  A♡  2♣  8♠ 9♠ 10♠

The side of the triangle are naturally scored (first column, last row, and the diagonal) alongside the last three rows and the first three columns.

For each of these collections of cards, which may contain more than 5 cards, the player find the 5 cards in that collection that create the highest scoring poker hand as determined by the table below.

For example, say we had a row with the cards 3♡,6♠,A♡,4♡,6♡,7♡. We would score this as a flush because the highest scoring poker hand is made of 3♡,A♡,4♡,6♡,7♡. Notice we did not count the possible pair of rank 6 cards in the hand. That means this row adds 20 pts to the score.

For another example, say in a second game, we had a triangle side with J♡,6♠,A♡,K♡,Q♡,10♡. We would score this as a straight flush because of the poker hand made of J♡,A♡,K♡,Q♡,10♡. Notice we did not count this hand as a straight or a flush. That means this side adds 75 pts to the score.

For a final example, say in a third game, we had another triangle side with 2♣,A♢,10♣,9♡,3♣,4♡. Then we would say this is a high card, because with any poker hand that can be made from these 6 cards, the best poker hand possible is a high card. That means this side adds 0 pts to the score.

Putting this all together reveals the score of the board given at the start of this section is 114 due to the following poker hands found in each row, column, and diagonal:

3 Building Poker Triangles

In this assignment you will design the model for this game. The model will maintain the state of the game and update itself when a client specifies moves. You are not required to make the game playable by a user at this point: only you-the-programmer can manipulate the model right now, and there is no mechanism yet for you-the-player to actually specify moves and play the game.

Finally, no method in your source code should exceed 50 lines. This hampers clarity of your code.

3.1 Cards

Start by modeling a card in the game of Poker Triangles. You are free to name the class and its methods whatever you want, but it must implement the Card interface given to you. You cannot modify the Card interface, but you may create a new interface that extends the Card interface to define new public methods other classes can rely on. Then your Card implementation can implement the new interface. This is how we can extend the functionality of code without changing existing code!

Your card implementation should behave like a proper “good citizen of Java”, and implement its own toString, equals and hashCode methods. Note that equality should work regardless of the Card implementation passed into equals. The toString method should render the cards as described above: e.g. "A♡" or "10♠", etc.

3.2 Expected operations

In order to play the game, the client would expect the following operations: start a new game, make a move, get the current state of the game, get the current score and know when the game has ended. These operations have been specified and documented in the provided PokerPolygons interface. You are not allowed to change the interface in any way!

A short explanation of most of the interface follows (the explanation here supplements the documentation provided in the interface):

3.3 Your Model Implementation

Implement the PokerPolygons interface by filling in the stubs in the PokerTriangles class:

  1. Design a suitable representation of this game. Think carefully about what fields and types you will need, and how possible values of the fields correspond to game states.

  2. Instantiating the game: Your class should define at least two constructors

    • A constructor with one argument that is the length of the sides of the triangular board. Note that invalid lengths should cause the constructor to throw an IllegalArgumentException

    • A constructor with two arguments, one that is the length of the sides of the triangular board and another that is a Random object to seed any random operations. Note that invalid lengths should cause the constructor to throw an IllegalArgumentException and a null Random object should throw an IllegalArgumentException

    Both constructors must initialize the game in a state that’s ready for someone to call startGame and begin playing. You may define whatever other constructors you wish; consider carefully all the methods you are expected to implement, and design your code to avoid as much duplication as possible. Keep in mind that a client should not be able to start a game without calling the startGame method!. This means there are methods, like those placeCardInPosition that will thrown an IllegalStateException if they are called before startGame is called and successfully completes.

  3. Encapsulation: Your PokerTriangles class should not have any public fields, nor any public methods other than constructors and the public methods required by the PokerPolygons interface.

Be sure to properly document your code with Javadoc as appropriate. Method implementations that inherit Javadoc need not provide their own unless they implement something different or in addition to what is specified in the inherited documentation.

3.4 Viewing the model

Our game should have some way of showing us the game board during game play. You have been provided with an empty PokerPolygonsTextualView interface that represents a view — we will add meaningful methods to this interface later. In this assignment, you must implement a class called PokerTrianglesTextualView in the cs3500.pokerpolygons.view package.

public interface PokerPolygonsTextualView {
 ...
}

public class PokerTrianglesTextualView implements PokerPolygonsTextualView{
  private final PokerPolygons<?> model;
  // ... any other fields you need

  public PokerTrianglesTextualView(PokerPolygons<?> model) {
    this.model = model;
  }

  // your implementation goes here
}

  1. Your class should at least have a constructor with exactly one argument of type PokerPolygons<?> this model provides all the information the view needs in order to be rendered. If this model given is null, a IllegalArgumentException should be thrown.

  2. The toString() method of this class returns a String that may be used to display the board. Here is an example rendering of a recently-started game with a side length of 5 and a hand size of 4; your toString() method should reproduce this:

     __
     __  __
     __  __  __
     __  __  __  __
     __  __  __  __  __
    Deck: 48
    Hand: 10♡, Q♡, 3♣, 7♠

    First, the board is shown. Each position is three characters wide and space separated. Filled positions are shown as the card placed there. If the card has two characters, then a space must be prepended (e.g. " 7♠"). Empty positions are shown as a space followed by two underscores " __". Then the deck’s size is shown in a single line. Finally, the player’s current hand is shown. Again, the cards are three characters wide and comma and space separated like the board. The cards are comma and space separated, but unlike the board, are not three characters wide, but as wide as they normally are printed (e.g. "7♠").

    In this view, every line should end with a newline character, except the final line — in this example, the first character of output is the '_' of the topmost position of the board and the final character is the '♠' of the "7♠".

3.5 Testing

You will need tests that assess whether your model implementation implements the behavior specified by the interfaces given and this assignment description.

To do that, you should create two new test classes. One of them should go in the cs3500.pokerpolygons package of the test directory, and it should contain tests for properties of the public model interface. To test implementation-specific details (e.g. details the client should not be aware of), you should create one last test class that you would place in the cs3500.pokerplygons.model.hw02 package itself, so that you can check package-private implementation details if needed.

Be mindful of which test cases you place in which test class! Technically, you could run all the tests from a single class. But using multiple classes like this helps convey to the reader of your code some of your thought processes behind each test: the reader should understand the examples first, then look at the tests of public behavior, and finally look at implementation-specific fiddly details.

Note: When you submit your full implementation, you will see automated tests that we wrote and run against your code. We give some of our test methods mnemonic names, so that you can try to deduce what our tests are checking for. Just because we have a test for a given scenario, though, does not mean that you shouldn’t write your own test case to confirm your understanding!

4 Package Management

To make sure that your packages are in the correct layout, you should tell IntelliJ to do the following. Do this early, before you’ve written much code, to ensure that your files wind up in the right locations automatically, instead of having to fix it afterward:

5 What to submit

Again, please ensure all of your project’s sources are in the cs3500.pokerpolygons.model.hw02 and cs3500.pokerpolygons.view packages, accordingly. Please ensure that your project’s test cases are in the packages explained above. Note that the model package refers to hw02, and the view does not. The autograder will give you an automatic 0 if it cannot compile your code!

6 Grading Standards

For this assignment, you will be graded on

7 Submission

Wait! Please read the assignment again and verify that you have not forgotten anything!

Please compress the src/ and test/ folders into a zip file and submit it. After submission, check your submitted code to ensure that you see two top-level folders: src/ and test/. If you see anything else, you did not create the zip file correctly! Please do not include your output/ or .idea/ directories — they’re not useful and you will list points for including them!

Please submit your assignment to https://handins.ccs.neu.edu/ by the above deadline. Then be sure to complete your self evaluation by the second deadline.

1In the textual representation here, “red” suits are simply shown as hollow shapes, while “black” suits are filled-in.

2For those versed in poker, aces are both high and low in this game.