ch.aplu.jcardgame
Class Card

java.lang.Object
  extended by ch.aplu.jcardgame.Card
All Implemented Interfaces:
java.lang.Comparable

public class Card
extends java.lang.Object
implements java.lang.Comparable

A class to represent individual playing cards.

General description of the JCardGame library:
The available suits and ranks of the game are defined using enumerations when creating a deck (instance of class Deck). The deck stores a JGameGrid actor (the "seed actor") for each suit and rank enumeration value that is used for displaying a card in a game grid window. But because the card image must often be scaled and rotated at runtime, the seed actor is never displayed directly, it only serves as store for the card image (and the card back image, called the card cover).

Suits and ranks are ordered. The priority is specified by the the order of the enumeration values given when the deck is created. The deck class also provides amethod dealingOut() that returns a user selectable number of card sets taken from the given suits/ranks, either randomly shuffled or ordered. Cards may also have a card value (card points) that is dynamically adaptable.

A card (instance of class Card) belongs to one of the suits and one of the ranks defined when a deck is created. Each card contains a link to its seed actor, but the Card class itself is not derived from the Actor class. To display a card in a game grid window, the seed actor's image is transformed at runtime with the required scale and rotation parameters and the current card actor is created with the transformed image. The card actor is then used as standard JGameGrid actor to show (and eventually move) the card image in the game grid window. When the scale and rotation parameters change, the old card actor is removed from the game grid and a new card actor is created and added to the game grid. It is a good idea to make a difference between a card as instance of the Card class that remains fixed through the lifetime of the card and its visual representation in a game grid window using the card actor that varies depending on the current scaling and rotation (like in the Model View Controller paradigm).

Normally a card is part of a set of cards called a hand and all cards of a hand are shown together when draw() is called. The properties of the visual arrangement is defined using 4 layout classes: StackLayout, RowLayout, ColumnLayout and FanLayout, all derived from the abstract class HandLayout. There are also "handless" cards that are either not yet inserted into a hand or removed from a hand. As stated before, the current card actor associated with the card must be dynamically calculated from its seed actor with the proper scaling and rotation values when the hand is displayed. Thus the card actor is only valid when the card is part of a hand and the hand was displayed. (Alternatively the card's attributeActor() method may be used to define its card actor.) Each card may also store an individual card value (card points).

Hands are very useful card containers, not only for the cards in a player's hand, but also for modeling card piles of any kind laying on the gambling table. Even when a hand contains a maximum of one card, putting it into a hand is preferable to an individual card because moving cards from one hand to another is simple using the hand's transfer() method.

A hand can be empty (and displayed as such without harm). A hand may even serve as card store without being displayed during the whole game. It is not rare to create between 10 to 20 hands in a 4-players game application.

A hand contains a array list of its cards, called the card list. This list determines the order the cards are painted in the game grid window (the "paint order"). Cards painted later are shown on top of other cards. Whenever a hand is drawn, the current card actor of every card is removed from the game grid, recalculated from its seed actor and added back to the game grid. This is a somewhat time-consuming operation and hands should only be redrawn when needed.

The Hand class provides many card list transforming operations, like sorting with several sort types, shuffling, shifting, reversing, etc. When the card list is modified, the change is not visible until the hand is redisplayed by calling draw(). To simplify redrawing, all hand modification methods have a boolean parameter that can be set true to perform redrawing automatically.

A card may be transferred from one hand to another using the transfer() method. The transfer can be animated by a sequence of card positions when the card moves from the source to the target hand. The transfer operation takes information from a TargetArea instance that includes the target location, the card orientation and a slide step (determines the speed). Once the target area parameters are set, all further transfer operations use them until they are redefined.


Field Summary
static boolean noVerso
          If true; all cards are always shown with the face up (for debugging purposes).
 
Constructor Summary
Card(Deck deck, int cardNb)
          Creates a card instance from given deck using the give card number Keep in mind that the current card actor is undefined (null) until the card is displayed in the gamegrid using the hand's draw() method or attributeActor() is called.
Card(Deck deck, T suit, R rank)
          Same as Create(deck, suit, rank, isVerso) with isVerso = false.
Card(Deck deck, T suit, R rank, boolean isVerso)
          Creates a card instance from given deck using the given suit and rank.
 
Method Summary
 CardActor associateActor(double scaleFactor, double rotationAngle)
          Calculates the current card actor with given scale factor and rotation angle from the seed actor taken from the card's deck.
 Card clone()
          Deep copy of a card with same attributes, including the card actor, but is handless (getHand() returns null).
 Card cloneAndAdd()
          Same as cloneAndAdd(double rotationAngle) with rotationAngle of current card.
 Card cloneAndAdd(double rotationAngle)
          Deep copy of a card with same attributes, including the card actor, but is handless (getHand() returns null).
 int compareTo(java.lang.Object other)
          Implementation of comparable interface.
 boolean equals(java.lang.Object obj)
          Checks if the given card has the same suit and rank as the current card (overrides Object.equals()).
 CardActor getCardActor()
          Returns the card actor reference of the card.
 int getCardNumber()
          Returns the card number of the current card.
 Deck getDeck()
          Returns the deck reference attributed to this card.
 java.awt.Dimension getDimension()
          Returns the current card dimension (scaling accounted).
 Hand getHand()
          Returns the hand the card belongs to.
 java.lang.Enum getRank()
          Returns the card's rank
 int getRankId()
          Returns the card's rank id.
 double getRotationAngle()
          Returns the current rotation angle.
 double getScaleFactor()
          Returns the current scale (zoom) factor.
 java.lang.Enum getSuit()
          Returns the card's suit.
 int getSuitId()
          Returns the card's suit id.
 int getValue()
          Returns the value of the card.
 int hashCode()
          Returns a hash code value for the object.
 boolean isInHand(Hand hand)
          Returns true, if the current card is part of the given hand.
 boolean isVerso()
          Returns true, if the card cover (back) will be shown.
 void removeFromHand(boolean redraw)
          Removes the card from its hand.
 void setVerso(boolean isVerso)
          Determines if the card's face or cover (back) will be shown.
 void slideToTarget(Location targetLocation, int slideStep)
          Same as slideToTarget(targetLocation, slideStep, blocking) with blocking = true.
 void slideToTarget(Location targetLocation, int slideStep, boolean blocking)
          If the card is added to the GameGrid, handless and visible, moves the card actor from current location to the given location using the given number of steps per GameGrid's simulation cycle.
 java.lang.String toString()
          Returns a string representation in the format "suit-rank".
 void transfer(Hand targetHand, boolean doDraw)
          Animated or non-animated transfer from current hand to new hand using the currently defined target area.
 void transferNonBlocking(Hand targetHand, boolean doDraw)
          Same as transfer(targetHand, doDraw), but the methods returns immediately.
 
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

noVerso

public static boolean noVerso
If true; all cards are always shown with the face up (for debugging purposes).

Constructor Detail

Card

public Card(Deck deck,
            T suit,
            R rank)
Same as Create(deck, suit, rank, isVerso) with isVerso = false.

Type Parameters:
T - the Enum type of the suit
R - the Enum type of the rank
Parameters:
deck - the deck where to the the cards seed actor
suit - the card suit
rank - the card rank

Card

public Card(Deck deck,
            T suit,
            R rank,
            boolean isVerso)
Creates a card instance from given deck using the given suit and rank. Keep in mind that the current card actor is undefined (null) until the card is displayed in the gamegrid using the hand's draw() method or attributeActor() is called.

Type Parameters:
T - the Enum type of the suit
R - the Enum type of the rank
Parameters:
deck - the deck where to the the cards seed actor
suit - the card suit
rank - the card rank
isVerso - if true the card cover (back) will be shown; otherwise the face will be shown

Card

public Card(Deck deck,
            int cardNb)
Creates a card instance from given deck using the give card number Keep in mind that the current card actor is undefined (null) until the card is displayed in the gamegrid using the hand's draw() method or attributeActor() is called.

Parameters:
deck - the deck where to the the cards seed actor
cardNb - the card number as defined in the Deck class
See Also:
Deck.getSuitId(int cardNb), Deck.getRankId(int cardNb)
Method Detail

associateActor

public CardActor associateActor(double scaleFactor,
                                double rotationAngle)
Calculates the current card actor with given scale factor and rotation angle from the seed actor taken from the card's deck.

Parameters:
scaleFactor - the scale factor (1: no scaling) applied to the image transformation
rotationAngle - the rotation angle (in degrees, clockwise) applied to the image transformation
Returns:
the current card actor (also stored as attribute)

clone

public Card clone()
Deep copy of a card with same attributes, including the card actor, but is handless (getHand() returns null).

Overrides:
clone in class java.lang.Object
Returns:
a clone of the current card

cloneAndAdd

public Card cloneAndAdd()
Same as cloneAndAdd(double rotationAngle) with rotationAngle of current card.


cloneAndAdd

public Card cloneAndAdd(double rotationAngle)
Deep copy of a card with same attributes, including the card actor, but is handless (getHand() returns null). If the current card actor is part of the game grid, the clone card is added to the game grid at the same location. If the card has no associated card actor, the card is simply cloned but not visible.

Parameters:
rotationAngle - the modified rotation angle of the card clone
Returns:
a clone of the current card

getCardActor

public CardActor getCardActor()
Returns the card actor reference of the card. The card actor changes if the card is part of a hand the hand's draw() methods are called or when attributeActor() is called.

Returns:
the card actor associated with this card; null, if no actor is yet associated

getCardNumber

public int getCardNumber()
Returns the card number of the current card. Cards are numbered in rank order from suit to suit in the given suit priority:

First suit from 0..nbCardsInSuit-1

Second suit from nbCardsInSuit..2*nbCardsInSuit-1

etc.

Returns:
the card number

getScaleFactor

public double getScaleFactor()
Returns the current scale (zoom) factor.

Returns:
the scale factor (<1: zoomed-out, >1: zoomed-in)

getRotationAngle

public double getRotationAngle()
Returns the current rotation angle.

Returns:
the rotation angle (in degrees, clockwise)

getDimension

public java.awt.Dimension getDimension()
Returns the current card dimension (scaling accounted).

Returns:
the scaled card dimension

getDeck

public Deck getDeck()
Returns the deck reference attributed to this card.

Returns:
the deck the card belongs to

getSuit

public java.lang.Enum getSuit()
Returns the card's suit.

Returns:
the suit of the card

getSuitId

public int getSuitId()
Returns the card's suit id.

Returns:
the suit id of the card

getRank

public java.lang.Enum getRank()
Returns the card's rank

Returns:
the rank of the card

getRankId

public int getRankId()
Returns the card's rank id.

Returns:
the rank id of the card

compareTo

public int compareTo(java.lang.Object other)
Implementation of comparable interface. Compares suits and ranks in the order defined in the SortType enumeration.

Specified by:
compareTo in interface java.lang.Comparable

isVerso

public boolean isVerso()
Returns true, if the card cover (back) will be shown.

Returns:
true, if the card cover (back) is active (sprite Id = 1); otherwise the card face is active (sprite Id = 0)

setVerso

public void setVerso(boolean isVerso)
Determines if the card's face or cover (back) will be shown. If the card is visible, it is immediately shown in the requested state.

Parameters:
isVerso - the visibilty used for the card; if true, the card cover (back) is active (sprite Id = 1); otherwise the card face is active (sprite Id = 0)

toString

public java.lang.String toString()
Returns a string representation in the format "suit-rank".

Overrides:
toString in class java.lang.Object
Returns:
a string representation of the card

isInHand

public boolean isInHand(Hand hand)
Returns true, if the current card is part of the given hand.

Returns:
true, if hand is part of hand's card list; otherwise false

getValue

public int getValue()
Returns the value of the card.

Returns:
the card value

removeFromHand

public void removeFromHand(boolean redraw)
Removes the card from its hand. Nothing happens if the card is handless. The card is removed from the hand's card list, but the the modification becomes only visible in a displayed hand, if redraw = true (or the hand is drawn or redrawn manually).

Parameters:
redraw - if true, a redraw is automatically done; otherwise redraw is not invoked

slideToTarget

public void slideToTarget(Location targetLocation,
                          int slideStep)
Same as slideToTarget(targetLocation, slideStep, blocking) with blocking = true.

Parameters:
targetLocation - the location where the card should arrive
slideStep - the number of steps moved in one cycle

slideToTarget

public void slideToTarget(Location targetLocation,
                          int slideStep,
                          boolean blocking)
If the card is added to the GameGrid, handless and visible, moves the card actor from current location to the given location using the given number of steps per GameGrid's simulation cycle. If the card is part of a hand, nothing happens (use transfer() instead). If the card is not part of the GameGrid, an error message is generated. Be aware that the paint order (which actor is shown on top) is given by the time the actors are added to the game grid. When a hand is drawn or redrawn, all card actors of the hand are reconstructed. Thus if the handless card is added later than the cards of a hand, it moves over the hand card's images. To make it move under the hand, redraw the hand after the handless card is added.

Parameters:
targetLocation - the location where the card should arrive
slideStep - the number of steps moved in one cycle
blocking - if true, the methods blocks until the card arrives at the target; otherwise the method returns immediately

transfer

public void transfer(Hand targetHand,
                     boolean doDraw)
Animated or non-animated transfer from current hand to new hand using the currently defined target area. If no target area is defined, the target hand location (that is defined, when the hand is drawn) is used as target location and the card transfer is animated.

For more advanced transferring option, define a target area with appropriate parameters.

The method blocks until the card arrives at the target. Arrived at the target, an atTarget() notification is triggered.

If the card is handless, nothing happens. (use slideToTarget() instead). See Hand.transfer() more more information.

Parameters:
targetHand - the hand where to move the card
doDraw - if true, the hand the card belongs to and the target hand are drawn (stacked arrangments are always drawn)
See Also:
Hand.transfer(Card card, Hand targetHand, boolean blocking, boolean redraw), TargetArea

transferNonBlocking

public void transferNonBlocking(Hand targetHand,
                                boolean doDraw)
Same as transfer(targetHand, doDraw), but the methods returns immediately. Use the atTarget callback to get a notification when the card arrived at its destination.

Parameters:
targetHand - the hand where to transfer the card
doDraw - if true, the hand the card belongs to and the target hand are drawn (stacked arrangments are always drawn)

equals

public boolean equals(java.lang.Object obj)
Checks if the given card has the same suit and rank as the current card (overrides Object.equals()).

Overrides:
equals in class java.lang.Object
Parameters:
obj - the object whose suit and rank is checked
Returns:
true, if the given object is of class Card and has the same suit and rank as the current card; otherwise false

hashCode

public int hashCode()
Returns a hash code value for the object. In accordance with the general contract for hashCode(). (Code from NetBeans IDE auto generate)

Overrides:
hashCode in class java.lang.Object

getHand

public Hand getHand()
Returns the hand the card belongs to. If the card is handless, returns null.

Returns:
the owner hand of the card; null, if card is handless