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.