Lab | Assigned | Design Due (In class) 10 AM |
Implement (In Lab) |
Demo (In Lab) |
Lab Due (In class) Friday 10 AM |
|||||
---|---|---|---|---|---|---|---|---|---|---|
21 | Oct | None | 22-23 | Oct | 29-30 | Oct | 1 | Nov |
goo()
calls a method foo()
, what goes on behind the scenes is that at the moment the call is made, foo()
's local variables are pushed onto Java's runtime stack. When foo()
returns, they are all popped and goo()
regains control where it
left off. Recursive algorithms make extensive use of this process for obvious reasons. Some calculators, like the HP48G, use a stack as the user interface. We will use a stack for the less serious and more entertaining task of making a card game.
Stack
This lab is the first of a multiweek sequence that will culminate in the creation of a working card game.
During this first week, you will create the abstraction of a stack of
cards. Our notion of a
stack of cards is similar to that of the Stack
you have been
learning about in class. The "last" card in a pile is whatever card was
last added to it, and cards are removed from this pile from last to first;
the pile is last-in, first-out (LIFO), like a Stack. You will
first implement a StackOfCards
, which we will subsequently use to
implement a Deck
.
You will need to create your own .java files for the classes that we have not provided. You will probably also need to make your own Startup.java to test your code, but you will not need to turn that file in. All grading will be done with the provided Startup.java file.
All methods below are public
. You may not add other public methods. All methods you add must be private. You are encouraged to add private methods where you see fit.
**See the JavaDoc for the same information presented differently**
Card
class
represents a card in our game. This class is modeled after the notion
of a two-dimensional sequence, as discussed in class. The API
for Card
does not disclose its representation.
While this is considered good design, you will have to become acquainted with
treating a card's rank and suit abstractly---so that
each card is positioned with respect to two orthogonal sequences.
A Card
also "knows" whether it is
visible (face-up) or not (face-down).
Here is the API for Card
.
Card()
Card
with base rank and suit.
By default, the card is invisible.
boolean isVisible()
PictureComponent getPicture()
PictureComponent
that holds the
Card's image. ** The SAME object must be returned every time! **
void setVisible(boolean visibility)
Card
according to the
parameter.
If the Card's image changes because its visibility is altered,
do not construct a new PictureComponent. Instead, use
the PictureComponent
's setImage(String filename)
on the existing PictureComponent
.
Card genNextRank()
Card
with the same suit as this one,
but with the next higher rank. If the maximum rank is reached and passed, a card of the lowest rank is returned.
Card genPrevRank()
Card
with the same suit as this one,
but with the next lower rank. If the minimum rank has been reached and passed, a card of the highest rank is returned.
Card genNextSuit()
Card
with the same rank as this one,
but with the next higher suit. If the maximum suit has been reached and passed, a card of the lowest suit is returned.
Card genPrevSuit()
Card
with the same rank as this one,
but with the next lower suit. If the minimum suit has been reached and passed, a card of the highest suit is returned.
int rankDiff(Card other)
other Card
and
this Card
(i.e. other - this; **all diff methods are this way).
int suitDiff(Card other)
other Card
and
this Card
.
boolean sameRankAs(Card other)
this Card
has the
same rank as
the other Card
.
boolean sameSuitAs(Card other)
this Card
has the
same suit as
the other Card
.
boolean isRankPrevOf(Card other)
this Card
has
rank one lower than that of
the other Card
. The Ace is the previous rank of a Two.
boolean isRankSuccOf(Card other)
this Card
has the rank
one higher than that of
the other Card
. The Two is the successor of the Ace.
boolean isAlternateSuitOf(Card other)
this Card
's "color" is
opposite that of
the other Card
.
String suitToString()
String
, for example "Spades"
String ranktoString()
String
, for example "Ace"
String toString()
String
containing the rank and suit of this card, for example "Ace of Spades"
Card
somewhat. The following conditions are
required. The card created
by the default constructor must be a Two of Clubs. If genNextRank is called on a Two of Clubs, a Three of Clubs
should be created. If a genNextRank should be called on a Three of Clubs, a Four of Clubs should be returned, and so on
up through Ace. If genNextRank is called on an Ace, a Two should be returned. The suits are ordered as follows:
Clubs, Diamonds, Hearts, Spades. Therefore, if genNextSuit is called on a Two of Clubs, a Two of Diamonds should be
returned, and so forth. genPrevRank and genPrevSuit should behave in a similar way.
ListOfCards
class
represents a list of Card
objects.
The code is patterned after
ListOfInts
.
Because of its similarity to the material discussed in class, we provide
this code for you.
ListOfCards()
boolean isEmpty()
boolean atEnd()
Card getItem()
Card
.
An error is thrown if the
list is empty, or if the current item is beyond the end of the list.
ListOfCards prepend(Card c)
Card
at the beginning of the list. For
convenience, a referece to the list is returned.
ListOfCards append(Card c)
Card
at the end of the list. For
convenience, a referece to the list is returned.
void setItem(Card c)
Card
.
An error is thrown if the
list is empty, or if the current item is beyond the end of the list.
void reset()
void next()
void insert(Card n)
Card
just before the current item, and
makes the inserted item the current one.
Card delete()
String toString()
String
representation of the entire list.
StackOfCards
is a simple class,
but is really the lifeblood of this lab.
Because
ListOfCards
seems similar to
StackOfCards
, it
may be tempting to implement
StackOfCards
by extending
ListOfCards
. However, this
is not the right thing to do. A list has many operations, such
as insert, delete, next, and reset, that are inappropriate for a stack.
If we extended
ListOfCards
, then the
resulting
StackOfCards
would
inherit all those methods. We do not want this.
A better approach is to implement
StackOfCards
by ensuring that it "has-a"
ListOfCards
as its underlying
implementation. Another way to implement a stack might have been with an array, but
we chose to use a linked list. This is why the stack is an abstract data type --
to the user of the StackOfCards class, it does not matter how it was implemented
as long as it works as expected. Having said that, you are nonetheless required to use ListOfCards
in your implementation.
StackOfCards()
StackOfCards
.
boolean isEmpty()
true
if there are no elements
in this StackOfCards
, and false otherwise.
Card peek()
Card
on this StackOfCards
.
Try to implement this method in terms of the other methods in this API.
void push(Card c)
Card
on top of the stack.
Card pop()
Card
from the stack and return it.
An attempt to pop
an empty stack should print an error message and return null.
String toString()
ListOfCards
's toString()
method here.
Startup
class to demonstrate that your classes work. To ease grading, this class is provided
for you. Ideally, the transcript generated by the reference implementation
and your code will be identical. You should not, however, rely solely on our Startup code
entirely during your own testing. After, for example, you finish the Card class,
you should make completely sure that it works as expected before moving on.
Startup()
Startup
object which tests the other classes in this lab.
Read the following carefully, and be sure to complete all parts below.
StackOfCards
Card
.
Compare the behavior of your card class to the reference implemenation.
StackOfCards
. Test it similarly.