This is CardPile.m in view mode; [Download] [Up]
/* indent:4 tabsize:8 font:fixed-width */
#import "CardPile.h"
@implementation CardPile
/*---------------------------------------------------------------------------
|
| + initialize
|
| returns: (id) [super initialize]
|
|----------------------------------------------------------------------------
|
| Sets a random seed based on the time before initializing the class
|
\----------------------------------------------------------------------------*/
+ initialize
{
srandom(time(0));
return [super initialize];
}
/*---------------------------------------------------------------------------
|
| - init
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Creates an empty list to manage the cards in the pile after
| initializing the object
|
\----------------------------------------------------------------------------*/
- init
{
[self initForCardSize:CS_SMALL];
return self;
}
/*---------------------------------------------------------------------------
|
| - initForCardSize:(CardSize)aSize
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Designated initializer for CardPile class.
|
\----------------------------------------------------------------------------*/
- initForCardSize:(CardSize)aSize
{
[super init];
cardSize = aSize;
cardList = [[List allocFromZone:[self zone]]init];
return self;
}
/*---------------------------------------------------------------------------
|
| - setCardSize:(CardSize)aSize
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Set the card size.
|
\----------------------------------------------------------------------------*/
- setCardSize:(CardSize)aSize
{
if (aSize != cardSize)
{
// have to change all the cards to the right class
id newCard;
id oldCard;
int i;
int cardCount = [cardList count];
for (i = 0; i < cardCount; i++)
{
oldCard = [cardList objectAt:i];
if (aSize == CS_SMALL)
{
newCard = [[SmallCard allocFromZone:[self zone]]
initSuit:[oldCard suit]
value:[oldCard value]
faceUp:[oldCard isFaceUp]];
}
else
{
newCard = [[Card allocFromZone:[self zone]]
initSuit:[oldCard suit]
value:[oldCard value]
faceUp:[oldCard isFaceUp]];
}
[cardList removeObjectAt:i];
[oldCard free];
[cardList insertObject:newCard at:i];
}
cardSize = aSize;
}
return self;
}
/*---------------------------------------------------------------------------
|
| - (CardSize)returnSize
|
| returns: (CardSize) current card size
|
|----------------------------------------------------------------------------
|
| Return the current card size.
|
\----------------------------------------------------------------------------*/
- (CardSize)returnSize
{
return cardSize;
}
/*---------------------------------------------------------------------------
|
| - free
|
| returns: (id) [super free]
|
|----------------------------------------------------------------------------
|
| Discards all of the card objects, the list they are contained in,
| and finally the CardPile itself.
|
\----------------------------------------------------------------------------*/
- free
{
[self freeCards];
[cardList free];
return [super free];
}
/*---------------------------------------------------------------------------
|
| - addCard:aCard
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Acts as a cover for insertCard::, but always adds cards to the top of
| a pile.
|
\----------------------------------------------------------------------------*/
- addCard:aCard
{
return [self insertCard:aCard at:CS_TOP];
}
/*---------------------------------------------------------------------------
|
| - insertCard:aCard at:(int) aPosition
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Adds a card to the pile at a specific position. The constants CS_TOP
| and CS_BOTTOM can be used to specify the top and bottom of the pile,
| respectively.
|
\----------------------------------------------------------------------------*/
- insertCard:aCard at:(int)aPosition
{
if (aPosition == CS_TOP)
{
[cardList addObject:aCard];
}
else
{
[cardList insertObject:aCard at:aPosition];
}
return self;
}
/*---------------------------------------------------------------------------
|
| - addPile:aCardPile
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Acts as a cover for insertCardPile::, but always adds cards to the top
| of a pile.
|
\----------------------------------------------------------------------------*/
- addPile:aCardPile
{
return [self insertPile:aCardPile at:CS_TOP];
}
/*---------------------------------------------------------------------------
|
| - addCopyOfPile:aCardPile
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Acts as a cover for insertCopyOfCardPile:at:, but always adds cards to
| the top of a pile.
|
\----------------------------------------------------------------------------*/
- addCopyOfPile:aCardPile
{
return [self insertCopyOfPile:aCardPile at:CS_TOP];
}
/*---------------------------------------------------------------------------
|
| - insertPile:aCardPile at:(int)aPosition
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Adds another pile of cards to this pile at a specific position. The
| constants CS_TOP and CS_BOTTOM can be used to specify the top and bottom
| of the pile, respectively.
|
\----------------------------------------------------------------------------*/
- insertPile:aCardPile at:(int)aPosition
{
int cardIndex;
if (aPosition == CS_TOP)
{
for (cardIndex = 0; cardIndex < [aCardPile cardCount]; cardIndex++)
{
[cardList addObject:[aCardPile cardAt:cardIndex]];
}
}
else
{
for (cardIndex = 0; cardIndex < [aCardPile cardCount]; cardIndex++)
{
[cardList insertObject:[aCardPile cardAt:cardIndex]at:aPosition++];
}
}
return self;
}
/*---------------------------------------------------------------------------
|
| - insertCopyOfPile:aCardPile at:(int)aPosition
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Adds another pile of cards to this pile at a specific position. The
| constants CS_TOP and CS_BOTTOM can be used to specify the top and bottom
| of the pile, respectively. The cards added are copies of (and
| independent from) the source cards.
|
\----------------------------------------------------------------------------*/
- insertCopyOfPile:aCardPile at:(int)aPosition
{
int cardIndex;
if (aPosition == CS_TOP)
{
for (cardIndex = 0; cardIndex < [aCardPile cardCount]; cardIndex++)
{
[cardList addObject:[[aCardPile cardAt:cardIndex]copy]];
}
}
else
{
for (cardIndex = 0; cardIndex < [aCardPile cardCount]; cardIndex++)
{
[cardList insertObject:[[aCardPile cardAt:cardIndex]copy]
at:aPosition++];
}
}
return self;
}
/*---------------------------------------------------------------------------
|
| - removeCard:aCard
|
| returns: (id) nil if the object wasn't in the CardPile
|
| (id) aCard if the card was removed
|
|----------------------------------------------------------------------------
|
| Remove a specific card from the pile. The card is not deallocated, it
| is up to the client to reuse or free the object. Note that this is the
| only way to remove a card from the pile.
|
\----------------------------------------------------------------------------*/
- removeCard:aCard
{
return [cardList removeObject:aCard];
}
/*---------------------------------------------------------------------------
|
| - addDeck
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Add a full deck of cards to the top of the pile, neatly ordered.
|
\----------------------------------------------------------------------------*/
- addDeck
{
int suitCounter, valueCounter;
for (valueCounter = CS_LOWVALUE;
valueCounter <= CS_HIGHVALUE;
valueCounter++)
{
for (suitCounter = CS_LOWSUIT;
suitCounter <= CS_HIGHSUIT;
suitCounter++)
{
if (cardSize == CS_SMALL)
{
[self insertCard:[[SmallCard allocFromZone:[self zone]]
initSuit:suitCounter
value:valueCounter]
at:CS_TOP];
}
else if (cardSize == CS_LARGE)
{
[self insertCard:[[Card allocFromZone:[self zone]]
initSuit:suitCounter
value:valueCounter]
at:CS_TOP];
}
}
}
return self;
}
/*---------------------------------------------------------------------------
|
| - empty
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Empties the card list describing the pile.
|
\----------------------------------------------------------------------------*/
- empty
{
[cardList empty];
return self;
}
/*---------------------------------------------------------------------------
|
| - freeCards
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Discards all of the card objects contained in the pile.
|
\----------------------------------------------------------------------------*/
- freeCards
{
[cardList freeObjects];
return self;
}
/*---------------------------------------------------------------------------
|
| - flip
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Turns the pile over, reversing the order of the cards and the
| orientation of each card.
|
\----------------------------------------------------------------------------*/
- flip
{
int cardIndex;
for (cardIndex = [cardList count]- 1; cardIndex >= 0; cardIndex--)
{
[cardList addObject:[[cardList removeObjectAt:cardIndex]flip]];
}
return self;
}
/*---------------------------------------------------------------------------
|
| - shuffle
|
| returns: (id) self
|
|----------------------------------------------------------------------------
|
| Randomly re-order all card objects contained in the pile.
|
\----------------------------------------------------------------------------*/
- shuffle
{
id temp;
int counter;
int swapIndex;
int cardCount = [cardList count];
for (counter = 0; counter < cardCount - 1; counter++)
{
swapIndex = ( random () % ( cardCount - counter)) + counter;
temp = [cardList objectAt:counter];
[cardList replaceObjectAt:counter with:[cardList objectAt:swapIndex]];
[cardList replaceObjectAt:swapIndex with:temp];
}
return self;
}
/*---------------------------------------------------------------------------
|
| - cardAt:(int) aPosition
|
| returns: (id) A card object for the given index, if it exists
|
| (id) nil if there is no card at the specified index
|
|----------------------------------------------------------------------------
|
| Allow a client to find out what card is at a given position in the pile.
| The constants CS_TOP and CS_BOTTOM can be used to specify the top and
| bottom of the pile, respectively.
|
\----------------------------------------------------------------------------*/
- cardAt:(int)aPosition
{
if (aPosition == CS_TOP)
{
aPosition = [cardList count]- 1;
if (aPosition == -1)
{
return nil;
}
}
return [cardList objectAt:aPosition];
}
/*---------------------------------------------------------------------------
|
| - (int) cardIndex:aCard
|
| returns: (int) A index for the given card, if it exists in the pile
|
| (int) NX_NOT_IN_LIST if the card isn't in the pile
|
|----------------------------------------------------------------------------
|
| Allow a client to find out what card is at a given position in the stack.
|
\----------------------------------------------------------------------------*/
- (int)cardIndex:aCard
{
return [cardList indexOf:aCard];
}
/*---------------------------------------------------------------------------
|
| - (int) cardCount
|
| returns: (int) The number of cards in the pile
|
|----------------------------------------------------------------------------
|
| Allow a client to find out how many cards are in the pile.
|
\----------------------------------------------------------------------------*/
- (int) cardCount
{
return [cardList count];
}
/*---------------------------------------------------------------------------
|
| - read:(NXTypedStream *) theStream
|
| returns: (int) self
|
|----------------------------------------------------------------------------
|
| Dearchive a CardPile.
|
\----------------------------------------------------------------------------*/
- read:(NXTypedStream *) theStream
{
[super read:theStream];
cardList = NXReadObject(theStream);
NXReadTypes(theStream, "i", &cardSize);
return self;
}
/*---------------------------------------------------------------------------
|
| - write:(NXTypedStream *) theStream
|
| returns: (int) self
|
|----------------------------------------------------------------------------
|
| Archive a CardPile.
|
\----------------------------------------------------------------------------*/
- write:(NXTypedStream *)theStream
{
[super write:theStream];
NXWriteObject(theStream, cardList);
NXWriteTypes(theStream, "i", &cardSize);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.