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.