CSE 413 14au Assignment 6 - Go Fish!
Due: Online via the Catalyst Dropbox by 11 pm, Thursday, Nov. 13, 2012.
Goals
For this project you will implement a computerized version of the card game Go Fish! The rules of the game are summarized below. The goals of this assignment are to gain experience with Ruby programming and with designing object-oriented programs. This writeup describes the basic constraints for the program that you should produce, but many of the details are up to you. In particular, the game rules may or may not correspond exactly to other versions of Go Fish that you know, but this shouldn't pose a problem. The goal is to gain experience with Ruby and object-oriented program design, not to become an expert at a particular card game.
The Game
Go Fish is played with a regular deck of 52 playing cards. Cards in a deck have one of four possible suits (Hearts, Diamonds, Spades, and Clubs), and face values of 2-10, Jack, Queen, King, and Ace. A game is played as follows.
- The deck of cards is shuffled into some random order, and each player gets 7 cards as their starting hand. The remaining cards are left in the deck.
- Added 11/10: Both players examine their hands. If a hand contains any pairs of cards with the same rank, the player discards those pairs.
- The players take turns. At each turn, one player asks the other
for cards with a particular rank (2-10, Jack, Queen, King, Ace).
- If the other player has one or more cards with that rank, they are given to the player who asked for them.
- If the other player has no cards with that rank, then the player doing the asking draws the next card from the deck of remaining cards. The other player may optionally say (or shout) "Go Fish!" to tell the player to draw from the deck.
- The players continue alternating turns until one player runs out of cards. When that happens, the winner is the player who has discarded the most pairs of cards during the game.
(There are variations on these rules in the real card game. For instance, in most versions, a player may only ask for cards that match the rank of one or more cards that they already hold. Also, in the real game, a player has a choice of whether to discard pairs or not. You can add these rules as extensions to your game, but they are not required.)
The Program
You should write a Ruby program that allows the user to play Go Fish with the computer. When the user runs the program, it should behave as follows:
- The computer should shuffle the 52 cards randomly, then deal 7 cards each into two separate hands for the user and the computer.
- Repeat the following steps until the game is over:
- Display the contents of the user's hand and report the number of cards in the computer's hand (but do not display them).
- Ask the user for a move. The user can enter any of the following commands:
- Request a card from the computer by entering a rank
2
-10
,j
,q
,k
, ora
. You can optionally allowJ
,Q
,K
, andA
to be used. - Quit the game by entering
x
. - Start a new game by entering
n
.
- Request a card from the computer by entering a rank
- When the user requests a card, the computer should do the following:
- If the computer is holding one or more cards with that rank in its hand, transfer those cards from the computer's hand to the user's hand.
- If the computer does not hold any cards with that rank, draw one card from the deck and add it to the user's hand.
- After transferring or drawing cards, any pairs of cards with the same rank in the user's hand should be discarded.
- The computer should then play a turn by picking a rank to request from the user's hand and either transfer or draw cards, depending on what is in the user's hand, and discard pairs if the computer holds any. The computer should pick a rank to ask for either randomly (easiest) or by asking for a rank that matches one in the computer's hand (a little harder).
- When either the user's or computer's hand is empty, the computer should announce the winner (the player that has discarded the most cards) and ask the user whether to play again.
The program should print additional messages to describe the progress of the game as needed.
Implementation
One of your jobs in this assignment is to decide what classes and objects you need, what messages those objects should respond to, and how the parts of your program should fit together. There are a few constraints that you must follow, given here. Beyond these specific requirements, your classes and objects should describe well thought-out individual concepts, and the parts of the program should interact with each other through small, simple interfaces.
Your implementation must include at least the following classes:
Card
: a single playing card. A card has a suit and a rank. This class should be very simple, with aninitialize
method to construct a newCard
given a suit and a rank, ato_s
method to return a string representation of the card, and any accessor methods needed to access the suit and rank of the card.Hand
: one player'sCard
s. This is a collection ofCard
objects representing the cards held by a single player. It is not necessarily ordered. It should include appropriate methods to add and remove cards, produce a string representation of a hand, search forCard
s in the hand, etc.Deck
: theCard
s remaining in the original deck. This is an ordered list ofCard
objects with methods to deal aCard
object from theDeck
and so forth.
Beyond these bare specifications, you will need logic to do things like create a randomly shuffled deck of 52 cards to start a game, interact with the user, play the game on behalf of the computer, keep track of the score, and so forth.
You should be prepared to let your design evolve as you work on the program. It is normal in designing object-oriented (or other) code to discover that decisions you made early in the process ought to be changed to make things simpler and cleaner. Don't be afraid to change things as you go -- don't get over-committed to your early decisions, and don't continue to hack at a design to get it to "work" when it would be better to do something different now that you have a better understanding of the problem. Be sure to start early enough so you have time to discard false starts and troublesome designs and evolve better designs as you go.
Your code should use Ruby collections, iterators, and blocks where this makes sense. For example, use the each
method instead of writing something like a Java for-loop to iterate through the elements in a collection, etc.
Your Ruby code can, if you wish, be stored in a single file, or you can split it up into separate files for individual classes or related classes. For this project, do whichever is simplest for you.
However, you should have one source file that is named fish.rb
,
and it should be possible to run your game with the command ruby fish.rb
(or the equivalent
on your system)
Extra Credit
A small amount of extra credit will be awarded for programs that include interesting extensions. A simple extension would enforce the restriction that players can only ask for cards that have the same rank as one they already hold in their hand. A more complex extension would be to make the computer smarter in its game play, for instance, instead of randomly asking for a particular card rank, keep track of the previous moves in the game and make smarter choices. A devious extension would be to add various "cheating" modes, where either the computer or the human user could peek at the other player's hand or do other evil things.
If you implement any extensions, include a file readme.txt
with your submission
that gives a brief explanation of your extensions. If you add any commands
or options to the game, include instructions on how to use them.
What to Hand In
Turn in a copy of your Ruby source files and, if you have one, the readme.txt
file
using the regular online collection dropbox. Be sure that your name is included
at
the
beginning
of
each of your files in
a comment.
Computer Science & Engineering University of Washington Box 352350 Seattle, WA 98195-2350 (206) 543-1695 voice, (206) 543-2969 FAX
Comments to adminanchor