This is GameCoordinator.m in view mode; [Download] [Up]
/* Generated by Interface Builder */
#import "GameCoordinator.h"
#import "AccidentView.h"
#import "DrivingAceView.h"
#import "EndOfLimitView.h"
#import "ExtraTankView.h"
#import "FlatTireView.h"
#import "GasolineView.h"
#import "Mile_25_View.h"
#import "Mile_50_View.h"
#import "Mile_75_View.h"
#import "Mile_100_View.h"
#import "Mile_200_View.h"
#import "OutOfGasView.h"
#import "PunctureProofView.h"
#import "RepairsView.h"
#import "RightOfWayView.h"
#import "RollView.h"
#import "SpareTireView.h"
#import "SpeedLimitView.h"
#import "StopView.h"
#import "mille.h"
#import "prototypes.h"
#import <appkit/appkit.h>
#import <assert.h>
#import <objc/objc-runtime.h>
#import <objc/List.h>
// This data structure is used to allocate cards and load the
// card deck.
cardDeckCell cardDeck[] = { { "AccidentView", N_ACCIDENT, C_ACCIDENT_HAZARD },
{ "DrivingAceView", N_DRIVING_ACE, C_DRIVING_ACE_SAFETY },
{ "EndOfLimitView", N_END_OF_LIMIT, C_END_OF_LIMIT_REMEDY },
{ "ExtraTankView", N_EXTRA_TANK, C_EXTRA_TANK_SAFETY },
{ "FlatTireView", N_FLAT_TIRE, C_FLAT_TIRE_HAZARD },
{ "GasolineView", N_GASOLINE, C_GASOLINE_REMEDY },
{ "OutOfGasView", N_OUT_OF_GAS, C_OUT_OF_GAS_HAZARD },
{ "PunctureProofView", N_PUNCTURE_PROOF, C_PUNCTURE_PROOF_SAFETY },
{ "RepairsView", N_REPAIRS, C_REPAIRS_REMEDY },
{ "RightOfWayView", N_RIGHT_OF_WAY, C_RIGHT_OF_WAY_SAFETY },
{ "RollView", N_ROLL, C_ROLL_REMEDY },
{ "SpareTireView", N_SPARE_TIRE, C_SPARE_TIRE_REMEDY },
{ "SpeedLimitView", N_SPEED_LIMIT, C_SPEED_LIMIT_HAZARD },
{ "StopView", N_STOP, C_STOP_HAZARD },
{ "Mile_25_View", N_25, C_25 },
{ "Mile_50_View", N_50, C_50 },
{ "Mile_75_View", N_75, C_75 },
{ "Mile_100_View", N_100, C_100 },
{ "Mile_200_View", N_200, C_200 },
0
};
@implementation GameCoordinator
- setMessagesText:( Text * ) anObject
{
float ourGray = [[ anObject opaqueAncestor ] backgroundGray ];
messagesText = anObject;
if( ourGray < 0.0 )
ourGray = [[ messagesText window ] backgroundGray ];
[[[ messagesText setEditable:NO ] setSelectable:NO ] setBackgroundGray:ourGray ];
return self;
}
- setDrawPile:anObject
{
drawPile = anObject;
[[[[ drawPile setTag:P_DRAW ] setTitle:"Draw Pile" ] setFrameMode:YES ] setCardsEnabled:YES ];
return self;
}
- setDiscardPile:anObject
{
discardPile = anObject;
[[[[ discardPile setTag:P_DISCARD ] setTitle:"Discard Pile" ] setFrameMode:YES ] setTrackingEnabled:YES ];
return self;
}
- ( Window * )gameWindow
{
return gameWindow;
}
- ( Window * )scoreWindow
{
return scoreWindow;
}
- ( Window * )cardsPlayedWindow
{
return cardsPlayedWindow;
}
- appDidInit:sender
{
int i;
NXRect handFrame = { -25, -25, 10, 10 };
HandTileView *computerHand;
// Create all of the cards and add them to the
// deck.
for( i = 0; i < ( sizeof( cardDeck ) / sizeof( cardDeckCell )); ++ i )
if( cardDeck[ i ].cardClassName ) {
int j;
id aCardClass = objc_getClass( cardDeck[ i ].cardClassName );
for( j = 0; j < cardDeck[ i ].numCards; ++j )
[ drawPile addCard:( CardView * )[[[[ aCardClass allocFromZone:[ NXApp zone ]] init ] setDragCoordinator:dragCoordinator ] setTag:cardDeck[ i ].cardType ] :self ];
}
// The computer hand tile view isn't on the board.
// we have to create it and locate it somewhere not in the window's
// frame.
computerHand = [ HandTileView newFrame:&handFrame ];
[[ gameWindow contentView ] addSubview:computerHand ];
[ computerPlayer setHand:computerHand ];
// Set the attributes of the views for the players.
[[ computerPlayer speedPile ] setTrackingEnabled:YES ];
[[ computerPlayer battlePile ] setTrackingEnabled:YES ];
[[ player speedPile ] setTrackingEnabled:YES ];
[[ player battlePile ] setTrackingEnabled:YES ];
[[ player safetyPile ] setTrackingEnabled:YES ];
[[[ player handPile ] setTrackingEnabled:YES ] setCardsEnabled:YES ];
[[ player distancePile ] setTrackingEnabled:YES ];
[ discardPile setTrackingEnabled:YES ];
// Initialize scores not maintained by
// the players.
[ OTHER_HAND_TOTAL_SCORE(computerPlayer) setIntValue:0 ];
[ OTHER_OVERALL_TOTAL_SCORE(computerPlayer) setIntValue:0 ];
[ OTHER_GAMES_SCORE(computerPlayer) setIntValue:0 ];
[ MAIN_HAND_TOTAL_SCORE(computerPlayer) setIntValue:0 ];
[ MAIN_OVERALL_TOTAL_SCORE(computerPlayer) setIntValue:0 ];
[ MAIN_GAMES_SCORE( computerPlayer ) setIntValue:0 ];
[ OTHER_HAND_TOTAL_SCORE(player) setIntValue:0 ];
[ OTHER_OVERALL_TOTAL_SCORE(player) setIntValue:0 ];
[ OTHER_GAMES_SCORE(player) setIntValue:0 ];
[ MAIN_HAND_TOTAL_SCORE(player) setIntValue:0 ];
[ MAIN_OVERALL_TOTAL_SCORE(player) setIntValue:0 ];
[ MAIN_GAMES_SCORE( player ) setIntValue:0 ];
[ gameWindow display ];
// Player goes first.
lastShuffler = computerPlayer ;
return [ self newGame ];
}
// Enough, Enough, Enough of this foolishness.
// Lets get to the game.
// The methods below IS THE GAME...
- newGame
{
[ player newGame ];
[ computerPlayer newGame ];
[ self newHand ];
return self;
}
- newHand
{
int i;
// Set the hand distance limit.
[ self setHandLimit:HAND_DISTANCE_LIMIT ];
// Clear and messages.
[[ messagesText selectAll:self ] replaceSel:"" ];
// Move all of the cards back to the draw pile
// and reinitialize the player for a new hand.
// Also erases scores for the player's hand.
[ discardPile sendAllCardsTo:drawPile ];
[ computerPlayer newHand ];
[ player newHand ];
// Make sure all of the cards are face down
// in the draw pile.
for( i = 0; i < NUMBER_OF_CARDS_IN_DECK; ++i )
[( CardView * )[[ drawPile subviews ] objectAt:i ] setShowTopFace:YES ];
[ self shuffleDeck ];
// Instruct all players to draw cards.
for( i = 0; i < ( HAND_SIZE - 1 ); ++i ) {
[ computerPlayer drawCard ];
[ player drawCard ];
}
// Clear the display tracking of what cards
// were played.
[ cardsTracker newHand ];
[ gameWindow display ];
// If the computer goes first then
// do it.
if( lastShuffler == computerPlayer )
[ computerPlayer playMove ];
return self;
}
- shuffleDeck
{
int i, j;
// The addCard: and removeCard: methods of card holder objects
// are too restrictive for shuffling. Therefore we're going
// do deal with the view hierarchy directly.
for( j = 0; j < 5; ++j ) {
extern void srandom( int );
srandom( time( NULL ));
for ( i = 0; i < NUMBER_OF_CARDS_IN_DECK; i++ ) {
int r = roll( 1, NUMBER_OF_CARDS_IN_DECK ) - 1;
CardHolder *firstCard = [[ drawPile subviews ] objectAt:i ],
*secondCard = [[ drawPile subviews ] objectAt:r ];
assert( r >= 0 && r < NUMBER_OF_CARDS_IN_DECK );
[ drawPile replaceSubview:firstCard with:[ secondCard removeFromSuperview ]];
if( r > ([[ drawPile subviews ] count ] - 1 ))
r -= 1;
[ drawPile addSubview:firstCard :NX_BELOW relativeTo:[[ drawPile subviews ] objectAt:r ]];
}
}
[ gameWindow display ];
return self;
}
- ( int )handLimit
{
return handLimit;
}
- setHandLimit:( int )aLimit
{
handLimit = aLimit;
return self;
}
- ( BOOL )willPlayerExtend
{
BOOL retVal = NO;
if( handLimit == HAND_DISTANCE_LIMIT )
if( NXRunAlertPanel( "", "Extension?", "Yes", "No", NULL ) == NX_ALERTDEFAULT ) {
[ self setHandLimit:HAND_DISTANCE_EXTENSION_LIMIT ];
[[ messagesText selectAll:self ] replaceSel:"Player chooses to hand." ];
retVal = YES;
}
return retVal;
}
- handOver
{
// Sum the hand and overall totals
// for both players.
[[ computerPlayer sumHand ] sumOverall ];
[[ player sumHand ] sumOverall ];
// Choose a new shuffler.
if( lastShuffler == player )
lastShuffler = computerPlayer;
else
lastShuffler = player;
// Is the game over?
if(([ OTHER_OVERALL_TOTAL_SCORE( player ) intValue ] >= GAME_DISTANCE_LIMIT ) || ([ OTHER_OVERALL_TOTAL_SCORE( computerPlayer ) intValue ] >= GAME_DISTANCE_LIMIT )) {
// Game over.
// Choose a winner and bump his score.
if([ OTHER_OVERALL_TOTAL_SCORE( player ) intValue ] != [ OTHER_OVERALL_TOTAL_SCORE( computerPlayer ) intValue ]) {
if([ OTHER_OVERALL_TOTAL_SCORE( player ) intValue ] >= [ OTHER_OVERALL_TOTAL_SCORE( computerPlayer ) intValue ])
[ OTHER_GAMES_SCORE( player ) setIntValue:[ OTHER_GAMES_SCORE( player ) intValue ] + 1 ];
else
[ OTHER_GAMES_SCORE( computerPlayer ) setIntValue:[ OTHER_GAMES_SCORE( computerPlayer ) intValue ] + 1 ];
[ MAIN_GAMES_SCORE( player ) setIntValue:[ OTHER_GAMES_SCORE( player ) intValue ]];
[ MAIN_GAMES_SCORE( computerPlayer ) setIntValue:[ OTHER_GAMES_SCORE( computerPlayer ) intValue ]];
}
// Start a new game.
[ self newGame ];
} else {
// Hand over.
// Start a new hand.
[ self newHand ];
}
return self;
}
- computerVsComputer:sender
{
id anAlert = NXGetAlertPanel( NULL, "Computer vs Computer", "Quit", NULL, NULL );
NXModalSession *session = [ NXApp beginModalSession:NULL for:anAlert ];
int modal;
id oldShuffler = lastShuffler,
lastPlayer = player;
do {
[ lastPlayer playMove ];
// Kludge.
// Has the shuffler changed?
// (indicates a new hand.)
if( oldShuffler == lastShuffler ) {
// New hand.
// Who went first?
// If the computer went first then
// have the player move. If the player is
// to go first then move now.
[ player playMove ];
// Computer goes next.
lastPlayer = computerPlayer;
oldShuffler = lastShuffler;
} else {
// Same hand.
// Choose next player to move.
if( lastPlayer == player )
lastPlayer = computerPlayer;
else
lastPlayer = player;
}
modal = [ NXApp runModalSession:session ];
} while( modal == NX_RUNCONTINUES );
[ NXApp endModalSession:session ];
NXFreeAlertPanel( anAlert );
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.