Info Lectures Assignments Staff Office Hours Hall of Fame Notes
Info Lectures Assignments Staff Office Hours Hall of Fame Notes

Crazy 8's

Assigned: 2020-02-12
Due Date: 2020-02-18 by 11:59PM U.S. Central Time

Assignment

Write a game engine for the Crazy 8's card game. The game engine must use the provided interface to communicate with the players of the game.

Get your copy of the assignment here: https://classroom.github.com/a/BkrgNo6F

The rubric can be found here.

Gradescope

There is no autograder for this assignment, but you still must submit your GitHub repository to Gradescope.

Goals

Assignment Specifications

Crazy 8's

You need to implement a system that can orchestrate games of Crazy 8's. There are several variants of this game; this is the version we want you to implement:

The game is played between 4 players with a standard 52 card deck, which should be shuffled at the beginning of the game. There is a draw pile and a discard pile. At the start of the game, each player is dealt 5 cards, and the rest of the deck becomes the draw pile. The top card of the draw pile is then drawn and placed into the discard pile, unless the card is an eight, in which case it should be shuffled back into the draw pile and another card should be drawn. Then a series of rounds are played:

In a round, each player takes a turn one after the other, where they must do one of the following:

  1. Discard a card in their hand that matches the suit or value of the card at the top of the discard pile
  2. Discard an eight in their hand, and name a new suit that the next player must match
  3. Add a card from the draw pile into their hand

Rounds are played until either the draw pile is empty, or a player is able to win by discarding all of the cards in their hand. The player who won will gain the summed value of the cards left in the other players' hands. In the event of a tie (no player manages to empty their hand), each player should receive the summed value of the other players' hands, not including their own hand.

Card point values:

Part 1: The Game Engine

First, some terminology:

Your game engine should:

  1. Take in 4 instances of a PlayerStrategy implementation
  2. Orchestrate a tournament of Crazy 8's with these strategies until a single strategy reaches a total score of 200 points

Note that the interface provides no way to tell a PlayerStrategy whether they won, lost, or how many points they earned. It is up to your game engine to decide how to keep track of this information in your application.

Your program will need a public static void main() and at least two implementations of PlayerStrategy to demonstrate your game engine working. You should report which of the PlayerStrategy implementations wins the tournament.

Things to keep in mind:

Part 2: Some Simple Strategies

You need to create at least two different classes that each implement the interface differently so that you can demonstrate your game engine working. Your implementations should only make legal plays (they should not try to cheat), but otherwise, they can play the game in whatever style you want. You should use these implementations to demonstrate a tournament in your main().

Extra Credit

You can earn some extra credit by extending this assignment. Some suggestions include:

Deliverables and Grading

  1. A program with a main() that uses your game engine to demonstrate running a Crazy 8's tournament
  2. A game engine that can run a game of Crazy 8's, as well as a tournament of those games
  3. At least two implementations of PlayerStrategy

Additional design things we will be looking for:

Use your best judgement to write the cleanest code you can; make sure you can justify any design decisions you make in code review. If something about your code doesn't feel right, investigate!

Try to make commits at regular intervals. You want to leave a clear trail of discrete pieces of progress that you've made as you work. Commits are cheap! Make lots of them. Once again, try to involve testing in your code development process; you don't have to write all of your tests before the code, but you should try to develop your code alongside your tests and vice versa. See this for a set of general guidelines for writing good commit messages.

Additional Info: Why an Interface?

We deliberately went out of our way to give you an interface PlayerStrategy rather than having you come up with your own way to manage how players interact with the game engine. Why?

Interfaces are a powerful tool for representing the concept of an abstract contract that can be implemented without the user knowing the specifics of the implementation. In this case, your game engine knows about certain methods in the PlayerStrategy interface that it can call, but it doesn't have to know anything about how those methods are overridden and implemented in a base class.

This gives us immense flexibility regarding how we choose to implement our Crazy 8's game engine. We don't have to worry about what specific player strategies exist; we only have to concern ourselves with upholding the contract, and leave those details to whoever is going to actually implement the interface.

Let's take a look at an example from the Java standard library: the Comparable interface, and Collections.sort(). Collections.sort() sorts collections, but only if it knows that the elements in that collection can be put in some kind of order. That's where Comparable comes in; Comparable defines a contract that classes must implement (the compareTo() method) in order for them to fulfill this requirement of "being orderable".

Here's a silly example:

public class Grape implements Comparable<Grape> {
    private int sweetness;

    // ...

    int compareTo(Grape other) {
        return this.sweetness - other.sweetness;
    }
}

And now I can sort a List<Grape> by sweetness with Collections.sort().

Collections.sort() doesn't know that it's sorting grapes; it only knows that given two instances of an object, it can compare and order them, because the class implements Comparable, so it can freely call the compareTo() method in the sorting algorithm. And the writers of Collections.sort() didn't have to concern themselves with the possibility of someone wanting to use their code to sort grapes, of all things.