This is Tenpile.m in view mode; [Download] [Up]
/* indent:4 tabsize:8 font:fixed-width */ #import "Tenpile.h" #import "localstrings.h" #import "TenpileTempDelegate.h" #import "TenpileSuitDelegate.h" #import "TenpileGameDelegate.h" #import "TenpilePrefs.h" static id _tenpileSharedInstance = nil; @implementation Tenpile + (Tenpile*) sharedInstance /*" Instead of the old method of calling SolGameController when you wanted to message the TenPile game module, you now call [Tenpile sharedInstance] and direct messages to the returned instance. You can use this to check if the game has been won, among other things. "*/ { return _tenpileSharedInstance; } - initFromBundle:(NSBundle*)aBundle withName:(NSString*)name /*" Extends our superclass method in order to set our shared instance variable. "*/ { [super initFromBundle:aBundle withName:name]; // This is used instead of having a global SolGameController() // function. It is assumed that this method will be called // only once and that our +sharedInstance method will return // the single instance. _tenpileSharedInstance = self; return self; } /*--------------------------------------------------------------------------- | | - startGame: | |---------------------------------------------------------------------------- | | Start a new game. Get confirmation from the user before aborting a | game in progress. | \----------------------------------------------------------------------------*/ - (void) startGame:sender { [super startGame:sender]; [self setupGame:YES]; } /*--------------------------------------------------------------------------- | | - restartGame: | |---------------------------------------------------------------------------- | | Restart the game in progress. | \----------------------------------------------------------------------------*/ - (void) restartGame:sender { [super restartGame:sender]; [self setupGame:NO]; } /*--------------------------------------------------------------------------- | | - setupGame:(BOOL)redeal | |---------------------------------------------------------------------------- | | Setup a new game. If "redeal" is true, deal a new deck, otherwise | use the same cards as the previous game. | \----------------------------------------------------------------------------*/ - (void) setupGame:(BOOL)redeal { int pileIndex, i; int cycle; int hiddenCards = [(TenpilePrefs*)prefs hiddenCards]; CardPileView* suitCardPiles[4]; CardPileView* gameCardPiles[10]; CardPileView* tempCardPiles[4]; [gameWindow disableFlushWindow]; //---------------------------------------------------------------- // Sync pile id's with current game window and set // preferences and delegates //---------------------------------------------------------------- suitCardPiles[0] = suitPileView1; suitCardPiles[1] = suitPileView2; suitCardPiles[2] = suitPileView3; suitCardPiles[3] = suitPileView4; for (i = 0; i < 4; i++) { [suitCardPiles[i] setBackgroundColor:desktopColor]; [suitCardPiles[i] setCardSize:cardSize]; [suitCardPiles[i] setDelegate:suitPileDelegate]; } gameCardPiles[0] = gamePileView1; gameCardPiles[1] = gamePileView2; gameCardPiles[2] = gamePileView3; gameCardPiles[3] = gamePileView4; gameCardPiles[4] = gamePileView5; gameCardPiles[5] = gamePileView6; gameCardPiles[6] = gamePileView7; gameCardPiles[7] = gamePileView8; gameCardPiles[8] = gamePileView9; gameCardPiles[9] = gamePileView10; for (i = 0; i < 10; i++) { [gameCardPiles[i] setBackgroundColor:desktopColor]; [gameCardPiles[i] setCardSize:cardSize]; [gameCardPiles[i] setDelegate:gamePileDelegate]; } tempCardPiles[0] = tempPileView1; tempCardPiles[1] = tempPileView2; tempCardPiles[2] = tempPileView3; tempCardPiles[3] = tempPileView4; for (i = 0; i < 4; i++) { [tempCardPiles[i] setBackgroundColor:desktopColor]; [tempCardPiles[i] setCardSize:cardSize]; [tempCardPiles[i] setDelegate:tempPileDelegate]; } [gamePileDelegate setSuitCardPileViews:suitCardPiles]; [gamePileDelegate setTempCardPileViews:tempCardPiles]; [tempPileDelegate setSuitCardPileViews:suitCardPiles]; [gameWindow display]; [gameWindow enableFlushWindow]; [gameWindow flushWindow]; //----------------------------------------------------------------------- // Initialize the gamePile to have a 1 shuffled deck. //----------------------------------------------------------------------- // Initialize the initial cardPile. if (!drawCardPile) { drawCardPile = [[CardPile allocWithZone:[self zone]] initForCardSize:cardSize]; } else [drawCardPile setCardSize:cardSize]; [drawCardPile empty]; if (redeal) { [drawCardPile addDeck]; [drawCardPile shuffle]; // make a copy of the CardPile for restart option if (!prevDeck) { prevDeck = [[CardPile allocWithZone:[self zone]] initForCardSize:cardSize]; } else { [prevDeck empty]; [prevDeck setCardSize:cardSize]; } [prevDeck addCopyOfPile:drawCardPile]; } else { if (prevDeck) { // copy the saved deck back to the game deck [prevDeck setCardSize:cardSize]; [drawCardPile addCopyOfPile:prevDeck]; } else { // this shouldn't happen, but just in case... [drawCardPile empty]; [drawCardPile addDeck]; [drawCardPile addDeck]; [drawCardPile shuffle]; } } //----------------------------------------------------------------------- // Initialize the "suit piles" as empty //----------------------------------------------------------------------- for (pileIndex = 0; pileIndex < 4; pileIndex++) { [[suitCardPiles[pileIndex] cardPile] empty]; [suitCardPiles[pileIndex] display]; } //----------------------------------------------------------------------- // Initialize the "temp piles" as empty //----------------------------------------------------------------------- for (pileIndex = 0; pileIndex < 4; pileIndex++) { [[tempCardPiles[pileIndex] cardPile] empty]; [tempCardPiles[pileIndex] display]; } //----------------------------------------------------------------------- // Initialize and deal cards to the 10 "user piles" //----------------------------------------------------------------------- for (pileIndex = 0; pileIndex < 10; pileIndex++) { [[gameCardPiles[pileIndex] cardPile] empty]; [gameCardPiles[pileIndex] display]; } for (cycle = 0; cycle < 5; cycle++) { for (pileIndex = 0; pileIndex < 10; pileIndex++) { CardPile* userPile = [gameCardPiles[pileIndex] cardPile]; Card* tempCard = [drawCardPile dealTopCard]; [userPile insertCard:tempCard at:CS_TOP]; if (cycle >= hiddenCards) [[userPile topCard] flip]; [gameCardPiles[pileIndex] display]; } } for (pileIndex = 0; pileIndex < 2; pileIndex++) { CardPile* userPile = [tempCardPiles[pileIndex] cardPile]; Card* tempCard = [drawCardPile dealTopCard]; [userPile insertCard:tempCard at:CS_TOP]; [[userPile topCard] flip]; [gameCardPiles[pileIndex] display]; } [gameWindow display]; [gameWindow makeKeyAndOrderFront:self]; } /*--------------------------------------------------------------------------- | | - endGame:sender | |---------------------------------------------------------------------------- | | End the game in progress. Discard the game window. | \----------------------------------------------------------------------------*/ - (void) endGame:sender { // close the game window [super endGame:sender]; // ****custom code here**** } /*--------------------------------------------------------------------------- | | - win | |---------------------------------------------------------------------------- | | Called when the game has been won. This is where you can insert fancy | winning routines, or just call the default (boring) routine. | \----------------------------------------------------------------------------*/ - (void) win { [super win]; // replace this with something wonderful } /*--------------------------------------------------------------------------- | | - checkForWin | |---------------------------------------------------------------------------- | | Called to check the state of the game. Always override (unless your | game is impossible to win). | \----------------------------------------------------------------------------*/ - (void) scheckForWin { if ([[suitPileView1 cardPile] cardCount] + [[suitPileView2 cardPile] cardCount] + [[suitPileView3 cardPile] cardCount] + [[suitPileView4 cardPile] cardCount] == 52) { [self win]; } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.