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.