Source/Game.m
changeset 7 428a194e3e59
parent 4 d781b00f3ed4
child 8 45c82a071aca
     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