Project 3 -- Figure Eight
Due: Tuesday, February 1, 2011
Objectives
- To understand the design goal of reusability
Introduction
This project will give you an opportunity to reuse classes and
methods you've already made to show how objects can work together beyond an
individual assignment. You're back to card playing in this project, where
you'll implement the card game Crazy Eights, which is the model
for Uno, if you've ever played that. Unlike the last project, the
goal here is to allow two or more users to play the game using a computer.
The Game
There are many variations of Crazy Eights, so here are the rules we'll be
using. The game is played with two standard 52-card decks, so there
are two instances of each card. At least two players are required, and
each player is dealt seven cards from the shuffled double-deck. One card
is placed face up for all to see.
Each player plays a card that either matches the suit or value of the
face-up card. So if the face-up card is a Jack of Clubs, the current
player may play any Jack or any Club (including the other Jack of Clubs).
Alternatively, the player may play any Eight, which acts as a wildcard.
The player playing the Eight then announces the suit that the card will act
as, which does not have to be the suit that is actually on the card. Play
then goes to the next player, who must repeat the process. That is, she
must play a card matching the suit or value of the new face-up card, play a
card of the called suit if the previous player put down an Eight, or play
an Eight herself. The winner is the first player to have no cards
remaining.
If a player has no playable cards in her hand, she must draw from the deck
until she can play something. A player can only pass if there are no cards
remaining to draw. However, a player may choose to draw as many cards as
she wants on her turn, even if she has a playable card in her hand.
Your Mission
Create a program that allows 2 or more humans to play Crazy Eights via
keyboard input and System.out for output. Play might look
something like this (the blue-green text is the user's input):
The game should announce when any player has exactly one card
remaining (as a warning to the other players). The game will
end when the computer announces a winner.
The Details
When first run, your program should ask the user for the number of players
and then ask for the name of each player. You should also print
instructions for how the user is to play the game. During each player's
turn, the following should happen:
- display the name of the person whose turn it is
- display the player's hand
- display the face-up card (including the suit that the card is acting
as, if the card is an eight)
- allow the user to input which card to play or else to indicate that the
user wishes to draw a card. In the picture above, I let the user play a
card by entering the number of the card in the displayed list. (The user
could also have input "d" to draw.) You may choose a different method for
user input. For example, you may choose for the user to type in the value
and suit of the card to be played.
- if the user drew a card, add a card to the player's hand and go to step
2. If the user selected a card from her hand to play, but the card is an
invalid play (not the right suit/value), tell the user so and go to step 2.
If the selected card is valid, display it as the new face-up card and
remove the card from the player's hand. If the card happened to be an
eight, you'll also have to somehow let the user input the suit that it will
act as. One way of doing this is in the picture above.
- Once a card has been played, check to see if the player has any cards
left. If not, you've got a winner. If just 1 card remains, announce that.
Otherwise, this player's turn is over, and you can move on to the next
player. Then go to step 1.
You should reuse your Card and Deck classes from Project 2 in
this project. Part of your job is to notice how easy or how difficult it
is to incorporate these classes. Does a class work as-is? With minimal
changes? With major changes? The best case is that a class works with no
changes, but depending on how you built it in Project 2, that may or may
not be possible. As this course goes on, we'll be talking a lot about how
to make a class reusable, so that changes to the code are minimized
despite changes to the context in which the code is used. For this
project, you just need to document (in a separate file to be included in
both the paper and electronic submissions) all of the changes you made to
the Card and Deck classes (methods changed, instance
variables added or removed, etc.)
You'll also need the following classes. This time, I'm only telling you
some of the methods and instance variables you'll need. You'll have to
figure out the rest on your own.
- Hand: This class represents the group of cards that a player is holding.
- instance variables:
- the player who owns this hand
- others?
- methods:
- drawCard: a method to add a card from the deck to a
hand
- removeCard: a method to remove a card from a hand and
return it.
This method will need at least one parameter specifying the card to remove.
You can do the specifying in many ways: as a Card object, as a suit
and value, or as an int representing the number from the displayed list, to
name a few.
- seekCard: a method like removeCard in that it returns
the Card specified in the parameter, but it doesn't remove it from
the player's hand.
- toString: a method that returns the hand as a printable string
- others?
- CrazyEights: This class contains everything specific to a game of Crazy Eights.
This class should allow two or more players to play a game.
- instance variables:
- You figure this out. What objects are absolutely necessary for
a game of Crazy Eights to take place?
- methods:
- Besides a constructor, only one method is really necessary: playGame.
This method will play a game using the rules and skeletal algorithm
described above. Remember to be modular. This is also the method where
you'll be reading input from the user. How do you read from the console
(also known as System.in)? Check out the docs for
the Scanner class, especially the examples at the top of the
document. It's pretty easy.
- Client or Application: A good rule of thumb is that
your main method should be very short, since it's only job is to
create appropriate objects and then call methods to start them running.
Here, the only thing
main needs to do is to create a CrazyEights object
and tell it to run playGame.
Remember to practice good programming skills:
- Comment before you write a method, not after.
- Test each method individually
- Private (helper) methods are your friend. Use them to modularize.
Grading
This project will be worth 50 points. It will be divided
up this way:
- 20 points for a correctly working and thoroughly tested game.
- 15 points for the overall design of your code, including correct
instance variables and methods.
- 10 points for modularity and understandability. Logic should be
straightforward and complex only when necessary. Don't forget about named
constants!
- 5 points for a good writeup of the changes you made to Card and Deck.
Remember to turn in both a paper and an electronic copy of your
project.
Administrative statement
Programming assignments, like homework assignments,
are individual projects. I encourage you to talk to others
about the general nature of the project and ideas about how to pursue it.
However, the technical work, the writing, and the inspiration behind these
must be substantially your own. If any person besides you contributes in
any way to the project, you must credit their work on your project.
Similarly, if you include information that you have gleaned from other
published sources, you must cite them as references. Looking at, and/or
copying, other people's programs or written work is inappropriate, and will
be considered cheating.