1.1 --- a/Source/Game.m Tue Mar 11 17:09:50 2008 -0700
1.2 +++ b/Source/Game.m Sun Mar 16 15:06:47 2008 -0700
1.3 @@ -22,6 +22,8 @@
1.4 */
1.5 #import "Game.h"
1.6 #import "Bit.h"
1.7 +#import "BitHolder.h"
1.8 +#import "QuartzUtils.h"
1.9
1.10
1.11 @interface Game ()
1.12 @@ -46,6 +48,9 @@
1.13 {
1.14 self = [super init];
1.15 if (self != nil) {
1.16 + _states = [[NSMutableArray alloc] init];
1.17 + _moves = [[NSMutableArray alloc] init];
1.18 + _currentMove = [[NSMutableString alloc] init];
1.19 _board = [board retain];
1.20 // Store a pointer to myself as the value of the "Game" property
1.21 // of my root layer. (CALayers can have arbitrary KV properties stored into them.)
1.22 @@ -60,11 +65,15 @@
1.23 {
1.24 [_board release];
1.25 [_players release];
1.26 + [_currentMove release];
1.27 + [_states release];
1.28 + [_moves release];
1.29 [super dealloc];
1.30 }
1.31
1.32
1.33 -@synthesize players=_players, currentPlayer=_currentPlayer, winner=_winner;
1.34 +@synthesize players=_players, currentPlayer=_currentPlayer, winner=_winner,
1.35 + currentMove=_currentMove, states=_states, moves=_moves;
1.36
1.37
1.38 - (void) setNumberOfPlayers: (unsigned)n
1.39 @@ -82,13 +91,35 @@
1.40 }
1.41
1.42
1.43 +- (void) addToMove: (NSString*)str;
1.44 +{
1.45 + [_currentMove appendString: str];
1.46 +}
1.47 +
1.48 +
1.49 +- (BOOL) _rememberState
1.50 +{
1.51 + if( self.isLatestTurn ) {
1.52 + [_states addObject: self.stateString];
1.53 + return YES;
1.54 + } else
1.55 + return NO;
1.56 +}
1.57 +
1.58 +
1.59 - (void) nextPlayer
1.60 {
1.61 + BOOL latestTurn = [self _rememberState];
1.62 if( ! _currentPlayer ) {
1.63 NSLog(@"*** The %@ Begins! ***", self.class);
1.64 self.currentPlayer = [_players objectAtIndex: 0];
1.65 } else {
1.66 self.currentPlayer = _currentPlayer.nextPlayer;
1.67 + if( latestTurn ) {
1.68 + [self willChangeValueForKey: @"currentTurn"];
1.69 + _currentTurn++;
1.70 + [self didChangeValueForKey: @"currentTurn"];
1.71 + }
1.72 }
1.73 NSLog(@"Current player is %@",_currentPlayer);
1.74 }
1.75 @@ -96,16 +127,88 @@
1.76
1.77 - (void) endTurn
1.78 {
1.79 - NSLog(@"--- End of turn");
1.80 + NSLog(@"--- End of turn (move was '%@')", _currentMove);
1.81 + if( self.isLatestTurn ) {
1.82 + [self willChangeValueForKey: @"maxTurn"];
1.83 + [_moves addObject: [[_currentMove copy] autorelease]];
1.84 + [_currentMove setString: @""];
1.85 + [self didChangeValueForKey: @"maxTurn"];
1.86 + }
1.87 +
1.88 Player *winner = [self checkForWinner];
1.89 if( winner ) {
1.90 NSLog(@"*** The %@ Ends! The winner is %@ ! ***", self.class, winner);
1.91 + [self _rememberState];
1.92 self.winner = winner;
1.93 } else
1.94 [self nextPlayer];
1.95 }
1.96
1.97
1.98 +- (unsigned) maxTurn
1.99 +{
1.100 + return _moves.count;
1.101 +}
1.102 +
1.103 +- (unsigned) currentTurn
1.104 +{
1.105 + return _currentTurn;
1.106 +}
1.107 +
1.108 +- (void) setCurrentTurn: (unsigned)turn
1.109 +{
1.110 + NSParameterAssert(turn<=self.maxTurn);
1.111 + if( turn != _currentTurn ) {
1.112 + if( turn==_currentTurn+1 ) {
1.113 + [self applyMoveString: [_moves objectAtIndex: _currentTurn]];
1.114 + } else {
1.115 + [CATransaction begin];
1.116 + [CATransaction setValue:(id)kCFBooleanTrue
1.117 + forKey:kCATransactionDisableActions];
1.118 + self.stateString = [_states objectAtIndex: turn];
1.119 + [CATransaction commit];
1.120 + }
1.121 + _currentTurn = turn;
1.122 + self.currentPlayer = [_players objectAtIndex: (turn % _players.count)];
1.123 + }
1.124 +}
1.125 +
1.126 +
1.127 +- (BOOL) isLatestTurn
1.128 +{
1.129 + return _currentTurn == MAX(_states.count,1)-1;
1.130 +}
1.131 +
1.132 +
1.133 +- (BOOL) animateMoveFrom: (BitHolder*)src to: (BitHolder*)dst
1.134 +{
1.135 + if( src==nil || dst==nil || dst==src )
1.136 + return NO;
1.137 + Bit *bit = [src canDragBit: src.bit];
1.138 + if( ! bit || ! [dst canDropBit: bit atPoint: GetCGRectCenter(dst.bounds)]
1.139 + || ! [self canBit: bit moveFrom: src to: dst] )
1.140 + return NO;
1.141 +
1.142 + ChangeSuperlayer(bit, _board.superlayer, -1);
1.143 + bit.pickedUp = YES;
1.144 + dst.highlighted = YES;
1.145 + [bit performSelector: @selector(setPickedUp:) withObject:nil afterDelay: 0.15];
1.146 + CGPoint endPosition = [dst convertPoint: GetCGRectCenter(dst.bounds) toLayer: bit.superlayer];
1.147 + [bit animateAndBlock: @"position"
1.148 + from: [NSValue valueWithPoint: NSPointFromCGPoint(bit.position)]
1.149 + to: [NSValue valueWithPoint: NSPointFromCGPoint(endPosition)]
1.150 + duration: 0.25];
1.151 + dst.bit = bit;
1.152 + dst.highlighted = NO;
1.153 + bit.pickedUp = NO;
1.154 +
1.155 + [src draggedBit: bit to: dst];
1.156 + [self bit: bit movedFrom: src to: dst];
1.157 + src = dst;
1.158 + return YES;
1.159 +}
1.160 +
1.161 +
1.162 #pragma mark -
1.163 #pragma mark GAMEPLAY METHODS TO BE OVERRIDDEN:
1.164
1.165 @@ -148,6 +251,11 @@
1.166 }
1.167
1.168
1.169 +- (NSString*) stateString {return @"";}
1.170 +- (void) setStateString: (NSString*)s { }
1.171 +
1.172 +- (BOOL) applyMoveString: (NSString*)move {return NO;}
1.173 +
1.174 @end
1.175
1.176