jens@0: /* This code is based on Apple's "GeekGameBoard" sample code, version 1.0. jens@0: http://developer.apple.com/samplecode/GeekGameBoard/ jens@0: Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved. jens@0: jens@0: Redistribution and use in source and binary forms, with or without modification, are permitted jens@0: provided that the following conditions are met: jens@0: jens@0: * Redistributions of source code must retain the above copyright notice, this list of conditions jens@0: and the following disclaimer. jens@0: * Redistributions in binary form must reproduce the above copyright notice, this list of jens@0: conditions and the following disclaimer in the documentation and/or other materials provided jens@0: with the distribution. jens@0: jens@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR jens@0: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jens@0: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI- jens@0: BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES jens@0: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jens@0: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN jens@0: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF jens@0: THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jens@0: */ jens@0: #import "Game.h" jens@0: #import "Bit.h" jens@0: jens@0: jens@0: @interface Game () jens@0: @property (copy) NSArray *players; jens@0: @property (assign) Player *currentPlayer, *winner; jens@0: @end jens@0: jens@0: jens@0: /** WARNING: THIS CODE REQUIRES GARBAGE COLLECTION! jens@0: ** This sample application uses Objective-C 2.0 garbage collection. jens@0: ** Therefore, the source code in this file does NOT perform manual object memory management. jens@0: ** If you reuse any of this code in a process that isn't garbage collected, you will need to jens@0: ** add all necessary retain/release/autorelease calls, and implement -dealloc methods, jens@0: ** otherwise unpleasant leakage will occur! jens@0: **/ jens@0: jens@0: jens@0: @implementation Game jens@0: jens@0: jens@0: + (NSString*) displayName jens@0: { jens@0: NSString* name = [self description]; jens@0: if( [name hasSuffix: @"Game"] ) jens@0: name = [name substringToIndex: name.length-4]; jens@0: return name; jens@0: } jens@0: jens@0: jens@0: - (id) initWithBoard: (CALayer*)board jens@0: { jens@0: self = [super init]; jens@0: if (self != nil) { jens@0: _board = [board retain]; jens@0: // Store a pointer to myself as the value of the "Game" property jens@0: // of my root layer. (CALayers can have arbitrary KV properties stored into them.) jens@0: // This is used by the -[CALayer game] category method defined below, to find the Game. jens@0: [board setValue: self forKey: @"Game"]; jens@0: } jens@0: return self; jens@0: } jens@0: jens@0: jens@0: - (void) dealloc jens@0: { jens@0: [_board release]; jens@0: [_players release]; jens@0: [super dealloc]; jens@0: } jens@0: jens@0: jens@0: @synthesize players=_players, currentPlayer=_currentPlayer, winner=_winner; jens@0: jens@0: jens@0: - (void) setNumberOfPlayers: (unsigned)n jens@0: { jens@0: NSMutableArray *players = [NSMutableArray arrayWithCapacity: n]; jens@0: for( int i=1; i<=n; i++ ) { jens@0: Player *player = [[Player alloc] initWithGame: self]; jens@0: player.name = [NSString stringWithFormat: @"Player %i",i]; jens@0: [players addObject: player]; jens@0: [player release]; jens@0: } jens@0: self.winner = nil; jens@0: self.currentPlayer = nil; jens@0: self.players = players; jens@0: } jens@0: jens@0: jens@0: - (void) nextPlayer jens@0: { jens@0: if( ! _currentPlayer ) { jens@0: NSLog(@"*** The %@ Begins! ***", self.class); jens@0: self.currentPlayer = [_players objectAtIndex: 0]; jens@0: } else { jens@0: self.currentPlayer = _currentPlayer.nextPlayer; jens@0: } jens@0: NSLog(@"Current player is %@",_currentPlayer); jens@0: } jens@0: jens@0: jens@0: - (void) endTurn jens@0: { jens@0: NSLog(@"--- End of turn"); jens@0: Player *winner = [self checkForWinner]; jens@0: if( winner ) { jens@0: NSLog(@"*** The %@ Ends! The winner is %@ ! ***", self.class, winner); jens@0: self.winner = winner; jens@0: } else jens@0: [self nextPlayer]; jens@0: } jens@0: jens@0: jens@0: #pragma mark - jens@0: #pragma mark GAMEPLAY METHODS TO BE OVERRIDDEN: jens@0: jens@0: jens@0: - (BOOL) canBit: (Bit*)bit moveFrom: (id)src jens@0: { jens@0: return YES; jens@0: } jens@0: jens@0: - (BOOL) canBit: (Bit*)bit moveFrom: (id)src to: (id)dst jens@0: { jens@0: return YES; jens@0: } jens@0: jens@0: - (void) bit: (Bit*)bit movedFrom: (id)src to: (id)dst jens@0: { jens@0: [self endTurn]; jens@0: } jens@0: jens@0: - (BOOL) clickedBit: (Bit*)bit jens@0: { jens@0: return YES; jens@0: } jens@0: jens@0: - (Player*) checkForWinner jens@0: { jens@0: return nil; jens@0: } jens@0: jens@0: jens@0: @end jens@0: jens@0: jens@0: jens@0: jens@0: @implementation Player jens@0: jens@0: jens@0: - (id) initWithGame: (Game*)game jens@0: { jens@0: self = [super init]; jens@0: if (self != nil) { jens@0: _game = game; jens@0: } jens@0: return self; jens@0: } jens@0: jens@0: jens@0: @synthesize game=_game, name=_name; jens@0: jens@0: - (BOOL) isCurrent {return self == _game.currentPlayer;} jens@0: - (BOOL) isFriendly {return self == _game.currentPlayer;} // could be overridden for games with partners jens@0: - (BOOL) isUnfriendly {return ! self.friendly;} jens@0: jens@0: - (int) index jens@0: { jens@0: return [_game.players indexOfObjectIdenticalTo: self]; jens@0: } jens@0: jens@0: - (Player*) nextPlayer jens@0: { jens@0: return [_game.players objectAtIndex: (self.index+1) % _game.players.count]; jens@0: } jens@0: jens@0: - (Player*) previousPlayer jens@0: { jens@0: return [_game.players objectAtIndex: (self.index-1) % _game.players.count]; jens@0: } jens@0: jens@0: - (NSString*) description jens@0: { jens@0: return [NSString stringWithFormat: @"%@[%@]", self.class,self.name]; jens@0: } jens@0: jens@0: @end jens@0: jens@0: jens@0: jens@0: jens@0: @implementation CALayer (Game) jens@0: jens@0: - (Game*) game jens@0: { jens@0: // The Game object stores a pointer to itself as the value of the "Game" property jens@0: // of its root layer. (CALayers can have arbitrary KV properties stored into them.) jens@0: for( CALayer *layer = self; layer; layer=layer.superlayer ) { jens@0: Game *game = [layer valueForKey: @"Game"]; jens@0: if( game ) jens@0: return game; jens@0: } jens@0: NSAssert1(NO,@"Couldn't look up Game from %@",self); jens@0: return nil; jens@0: } jens@0: jens@0: @end