ftp.nice.ch/pub/next/games/card/Solitaire.2.1.s.tar.gz#/Solitaire.2.1.s/FortyThieves/FortyThieves.m

This is FortyThieves.m in view mode; [Download] [Up]

/* indent:4  tabsize:8  font:fixed-width */

#import "FortyThieves.h"
#import "localstrings.h"
#import "FTDrawDelegate.h"
#import "FTSuitDelegate.h"
#import "FTGameDelegate.h"
#import "FTAlertPanel.h"

@implementation FortyThieves


/*---------------------------------------------------------------------------
|
|    - startGame:
|
|    returns:    (id)  self
|
|----------------------------------------------------------------------------
|
|    Start a new game.  Get confirmation from the user before aborting a 
|    game in progress.
|			
\----------------------------------------------------------------------------*/

- startGame:sender
{
    [super startGame:sender];
    return [self setupGame:YES];
}


/*---------------------------------------------------------------------------
|
|    - restartGame:
|
|    returns:  (id) self
|
|----------------------------------------------------------------------------
|
|    Restart the game in progress.
|			
\----------------------------------------------------------------------------*/

- restartGame:sender
{
    [super restartGame:sender];
    return [self setupGame:NO];
}


/*---------------------------------------------------------------------------
|
|    - setupGame:(BOOL)redeal
|
|    returns:  (id) self
|
|----------------------------------------------------------------------------
|
|    Setup a new game.  If "redeal" is true, deal a new deck, otherwise
|    use the same cards as the previous game.
|			
\----------------------------------------------------------------------------*/

- setupGame:(BOOL)redeal
{
    int pileIndex, i;
    int cycle;
    id  suitCardPiles[8];
    id  gameCardPiles[10];
    id  drawCardPile;

    [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;
    suitCardPiles[4] = suitPileView5;
    suitCardPiles[5] = suitPileView6;
    suitCardPiles[6] = suitPileView7;
    suitCardPiles[7] = suitPileView8;

    for (i = 0; i < 8; i++)
    {
        [suitCardPiles[i] setBackgroundColor:desktopColor];
        [suitCardPiles[i] setCardSize:cardSize];
        [suitCardPiles[i] setDelegate:suitPileDelegate];
    }
    [gamePileDelegate setSuitCardPileViews:suitCardPiles];
    [discardPileDelegate setSuitCardPileViews:suitCardPiles];
    [discardPileView setBackgroundColor:desktopColor];
    [discardPileView setCardSize:cardSize];
    [discardPileView setDelegate:discardPileDelegate];
    
    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];
    }
    
    [drawPileView setBackgroundColor:desktopColor];
    [drawPileView setCardSize:cardSize];
    drawCardPile = [drawPileView cardPile];
    [drawPileDelegate setDiscardCardPileView:discardPileView];
    [drawPileView setDelegate:drawPileDelegate];
    
    [gameWindow display];
    [gameWindow reenableFlushWindow];
    [gameWindow flushWindow];

    //-----------------------------------------------------------------------
    //    Initialize the drawPileView to have a 2 shuffled decks.
    //-----------------------------------------------------------------------
    
    [drawCardPile freeCards];
    if (redeal)
    {
        [drawCardPile addDeck];
        [[drawCardPile addDeck] shuffle];
	
	// make a copy of the CardPile for restart option
	if (!prevDeck)
	{
	    prevDeck = [[CardPile allocFromZone:[self zone]]
	                           initForCardSize:cardSize];
	}
	else
	{
	    [prevDeck freeCards];
	    [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 freeCards];
	    [drawCardPile addDeck];
	    [[drawCardPile addDeck] shuffle];
	}
    }
    
    //-----------------------------------------------------------------------
    //    Initialize the "suit piles" and discard pile as empty
    //-----------------------------------------------------------------------

    [[discardPileView cardPile] freeCards];
    [discardPileView display];
    
    for (pileIndex = 0; pileIndex < 8; pileIndex++)
    {
        [[suitCardPiles[pileIndex] cardPile] freeCards];
        [suitCardPiles[pileIndex] display];
    }

    //-----------------------------------------------------------------------
    //    Initialize and deal cards to the 10 "user piles"
    //-----------------------------------------------------------------------

    for (pileIndex = 0; pileIndex < 10; pileIndex++)
    {
        [[gameCardPiles[pileIndex] cardPile] freeCards];
    }
    
    for (cycle = 0; cycle < 4; cycle++)
    {
	for (pileIndex = 0; pileIndex < 10; pileIndex++)
	{
	    id userPile = [gameCardPiles[pileIndex] cardPile];
	    id tempCard = [drawCardPile cardAt:CS_TOP];
	    [drawCardPile removeCard:tempCard];
	    [userPile insertCard:tempCard at:CS_TOP];
	    [[userPile cardAt:CS_TOP] flip];
	    [gameCardPiles[pileIndex] display];
	}
    }

    [gameWindow display];
    [gameWindow makeKeyAndOrderFront:self];
    return self;
}


/*---------------------------------------------------------------------------
|
|    - endGame:sender
|
|    returns:  (id) self
|
|----------------------------------------------------------------------------
|
|    End the game in progress.  Discard the game window.
|			
\----------------------------------------------------------------------------*/

- endGame:sender
{
    // close the game window
    [super endGame:sender];

    // ****custom code here****
    
    return self;
}

/*---------------------------------------------------------------------------
|
|    - win
|
|     returns: (id) self
|
|----------------------------------------------------------------------------
|
|    Called when the game has been won.  This is where you can insert fancy
|    winning routines, or just call the default (boring) routine.
|
\----------------------------------------------------------------------------*/

- win
{
    [super win];  // replace this with something wonderful
    return self;
}


/*---------------------------------------------------------------------------
|
|    - checkForWin
|
|    returns: (id) self
|
|----------------------------------------------------------------------------
|
|    Called to check the state of the game.  Always override (unless your
|    game is impossible to win).
|
\----------------------------------------------------------------------------*/

- checkForWin
{
    if ([[suitPileView1 cardPile] cardCount] +
            [[suitPileView2 cardPile] cardCount] +
            [[suitPileView3 cardPile] cardCount] +
            [[suitPileView4 cardPile] cardCount] +
	    [[suitPileView5 cardPile] cardCount] +
	    [[suitPileView6 cardPile] cardCount] +
	    [[suitPileView7 cardPile] cardCount] +
	    [[suitPileView8 cardPile] cardCount] == 104)
    {
        [self win];
    }
    return self;
}


- peekAtNextCard:sender
{
    id peekCardPile = [peekCardView cardPile];
    id nextCard = [[drawPileView cardPile] cardAt:CS_TOP];
    id peekCard;
    
    if(nextCard != nil){
	peekCard = [[SmallCard allocFromZone:[self zone]] 
			    initSuit:[nextCard suit]
			    value:[nextCard value]
			    faceUp:YES];
	[peekCardView setDrawOutline:NO];
	[peekCardView setBackgroundColor:NX_COLORLTGRAY];
	[peekCardPile freeCards];
	[peekCardPile addCard:peekCard];
	[peekCardView display];
	[peekPanel run:self];
    }
    else{
	NXRunAlertPanel(LOCALIZED_GAME_NAME,LOCALIZED_NO_STOCK_CARD,
	"OK", NULL, NULL);
    }
    
    return self;
}

@end

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.