More tweaks, including a "reversed" property for Grids to show the second player's perspective without turning the pieces upside-down.
authorJens Alfke <jens@mooseyard.com>
Wed Jul 09 17:07:45 2008 -0700 (2008-07-09)
changeset 1573f8c889f053
parent 14 4585c74d809c
child 16 28392c9a969f
More tweaks, including a "reversed" property for Grids to show the second player's perspective without turning the pieces upside-down.
Source/BitHolder.m
Source/BoardView.h
Source/BoardView.m
Source/CheckersGame.m
Source/GGBLayer.h
Source/GGBLayer.m
Source/Game.h
Source/Game.m
Source/Grid.h
Source/Grid.m
Source/HexchequerGame.m
Source/Turn.h
Source/Turn.m
     1.1 --- a/Source/BitHolder.m	Tue Jul 08 20:32:52 2008 -0700
     1.2 +++ b/Source/BitHolder.m	Wed Jul 09 17:07:45 2008 -0700
     1.3 @@ -54,6 +54,8 @@
     1.4          }
     1.5          setObj(&_bit,bit);
     1.6          ChangeSuperlayer(bit,self,-1);
     1.7 +        if( bit )
     1.8 +            NSLog(@"%@: xform = \n%@",bit,StringFromTransform3D(bit.aggregateTransform));//TEMP
     1.9      }
    1.10  }
    1.11  
     2.1 --- a/Source/BoardView.h	Tue Jul 08 20:32:52 2008 -0700
     2.2 +++ b/Source/BoardView.h	Wed Jul 09 17:07:45 2008 -0700
     2.3 @@ -56,8 +56,6 @@
     2.4  
     2.5  - (void) createGameBoard;
     2.6  
     2.7 -- (void) reverseBoard;
     2.8 -
     2.9  - (IBAction) enterFullScreen: (id)sender;
    2.10  
    2.11  - (CGRect) gameBoardFrame;
     3.1 --- a/Source/BoardView.m	Tue Jul 08 20:32:52 2008 -0700
     3.2 +++ b/Source/BoardView.m	Wed Jul 09 17:07:45 2008 -0700
     3.3 @@ -71,13 +71,6 @@
     3.4  }
     3.5  
     3.6  
     3.7 -- (void) reverseBoard
     3.8 -{
     3.9 -    [_gameboard setValue: [NSNumber numberWithDouble: M_PI]
    3.10 -              forKeyPath: @"transform.rotation"];
    3.11 -}
    3.12 -
    3.13 -
    3.14  - (Game*) game
    3.15  {
    3.16      return _game;
    3.17 @@ -103,14 +96,6 @@
    3.18  }
    3.19  
    3.20  
    3.21 -- (BOOL) canMakeMove
    3.22 -{
    3.23 -    return _game != nil
    3.24 -        && _game.currentPlayer.local
    3.25 -        && _game.currentTurn.status < kTurnComplete;
    3.26 -}
    3.27 -
    3.28 -
    3.29  - (CGRect) gameBoardFrame
    3.30  {
    3.31      return self.layer.bounds;
    3.32 @@ -120,7 +105,7 @@
    3.33  - (void)resetCursorRects
    3.34  {
    3.35      [super resetCursorRects];
    3.36 -    if( self.canMakeMove )
    3.37 +    if( _game.okToMove )
    3.38          [self addCursorRect: self.bounds cursor: [NSCursor openHandCursor]];
    3.39  }
    3.40  
    3.41 @@ -225,7 +210,7 @@
    3.42  
    3.43  - (void) mouseDown: (NSEvent*)ev
    3.44  {
    3.45 -    if( ! self.canMakeMove ) {
    3.46 +    if( ! _game.okToMove ) {
    3.47          NSBeep();
    3.48          return;
    3.49      }
     4.1 --- a/Source/CheckersGame.m	Tue Jul 08 20:32:52 2008 -0700
     4.2 +++ b/Source/CheckersGame.m	Wed Jul 09 17:07:45 2008 -0700
     4.3 @@ -98,6 +98,7 @@
     4.4      grid.cellColor = CreateGray(0.0, 0.25);
     4.5      grid.altCellColor = CreateGray(1.0, 0.25);
     4.6      grid.lineColor = nil;
     4.7 +    grid.reversed = ! [[self.players objectAtIndex: 0] isLocal];
     4.8  
     4.9      for( int i=0; i<32; i++ ) {
    4.10          int row = i/4;
     5.1 --- a/Source/GGBLayer.h	Tue Jul 08 20:32:52 2008 -0700
     5.2 +++ b/Source/GGBLayer.h	Wed Jul 09 17:07:45 2008 -0700
     5.3 @@ -43,6 +43,8 @@
     5.4      and update every other layer that shares the same style dictionary. */
     5.5  - (void) setValue: (id)value ofStyleProperty: (NSString*)prop;
     5.6  
     5.7 +- (CATransform3D) aggregateTransform;
     5.8 +
     5.9  @end
    5.10  
    5.11  
    5.12 @@ -58,3 +60,4 @@
    5.13  
    5.14  CGColorRef GetEffectiveBackground( CALayer *layer );
    5.15  
    5.16 +NSString* StringFromTransform3D( CATransform3D xform );
     6.1 --- a/Source/GGBLayer.m	Tue Jul 08 20:32:52 2008 -0700
     6.2 +++ b/Source/GGBLayer.m	Wed Jul 09 17:07:45 2008 -0700
     6.3 @@ -124,6 +124,30 @@
     6.4  }
     6.5  
     6.6  
     6.7 +- (CATransform3D) aggregateTransform
     6.8 +{
     6.9 +    CATransform3D xform = CATransform3DIdentity;
    6.10 +    for( CALayer *layer=self; layer; layer=layer.superlayer ) {
    6.11 +        xform = CATransform3DConcat(layer.transform,xform);
    6.12 +        xform = CATransform3DConcat(layer.sublayerTransform,xform);
    6.13 +    }
    6.14 +    return xform;
    6.15 +}
    6.16 +
    6.17 +
    6.18 +NSString* StringFromTransform3D( CATransform3D xform )
    6.19 +{
    6.20 +    NSMutableString *str = [NSMutableString string];
    6.21 +    const CGFloat *np = (const CGFloat*)&xform;
    6.22 +    for( int i=0; i<16; i++ ) {
    6.23 +        if( i>0 && (i%4)==0 )
    6.24 +            [str appendString: @"\n"];
    6.25 +        [str appendFormat: @"%7.2f ", *np++];
    6.26 +    }
    6.27 +    return str;
    6.28 +}
    6.29 +
    6.30 +
    6.31  
    6.32  #if TARGET_OS_IPHONE
    6.33  
     7.1 --- a/Source/Game.h	Tue Jul 08 20:32:52 2008 -0700
     7.2 +++ b/Source/Game.h	Wed Jul 09 17:07:45 2008 -0700
     7.3 @@ -77,6 +77,10 @@
     7.4  @property unsigned currentTurnNo;
     7.5  @property (readonly) BOOL isLatestTurn;
     7.6  
     7.7 +/** Check this before the user begins a move action (mouse-down on a bit, etc.)
     7.8 +    It's YES if it's OK to move,  or NO if the current move is finished or it's another player's turn. */
     7.9 +@property (readonly) BOOL okToMove;
    7.10 +
    7.11  @property BOOL requireConfirmation;
    7.12  - (void) cancelCurrentTurn;
    7.13  - (void) confirmCurrentTurn;
     8.1 --- a/Source/Game.m	Tue Jul 08 20:32:52 2008 -0700
     8.2 +++ b/Source/Game.m	Wed Jul 09 17:07:45 2008 -0700
     8.3 @@ -219,6 +219,23 @@
     8.4  }
     8.5  
     8.6  
     8.7 +- (BOOL) okToMove
     8.8 +{
     8.9 +    Turn *latest = self.latestTurn;
    8.10 +    if( latest.player.local && latest.status < kTurnComplete ) {
    8.11 +        // Automatically skip from latest finished turn, since board state is the same:
    8.12 +        unsigned latestTurnNo = self.maxTurnNo;
    8.13 +        if( _currentTurnNo==latestTurnNo-1 ) {
    8.14 +            NSLog(@"okToMove: skipping from turn %i to %i",_currentTurnNo,latestTurnNo);
    8.15 +            self.currentTurnNo = latestTurnNo;
    8.16 +        }
    8.17 +        if( _currentTurnNo==latestTurnNo )
    8.18 +            return YES;
    8.19 +    }
    8.20 +    return NO;
    8.21 +}
    8.22 +
    8.23 +
    8.24  - (void) endTurn
    8.25  {
    8.26      Turn *curTurn = self.currentTurn;
     9.1 --- a/Source/Grid.h	Tue Jul 08 20:32:52 2008 -0700
     9.2 +++ b/Source/Grid.h	Wed Jul 09 17:07:45 2008 -0700
     9.3 @@ -32,7 +32,7 @@
     9.4      Class _cellClass;                                   
     9.5      CGColorRef _cellColor, _lineColor;                  
     9.6      CGImageRef _backgroundImage;
     9.7 -    BOOL _usesDiagonals, _allowsMoves, _allowsCaptures;
     9.8 +    BOOL _usesDiagonals, _allowsMoves, _allowsCaptures, _reversed;
     9.9      NSMutableArray *_cells;                             // Really a 2D array, in row-major order.
    9.10  }
    9.11  
    9.12 @@ -55,6 +55,7 @@
    9.13  @property CGImageRef backgroundImage;           // Image drawn in background, behind lines and cells
    9.14  @property BOOL usesDiagonals;                   // Affects GridCell.neighbors, for rect grids
    9.15  @property BOOL allowsMoves, allowsCaptures;     // Can pieces be moved, and can they land on others?
    9.16 +@property BOOL reversed;                        // Reverses board (rotates 180°) by exchanging cell positions
    9.17  
    9.18  @property (readonly) NSArray *cells;
    9.19  
    10.1 --- a/Source/Grid.m	Tue Jul 08 20:32:52 2008 -0700
    10.2 +++ b/Source/Grid.m	Wed Jul 09 17:07:45 2008 -0700
    10.3 @@ -112,7 +112,7 @@
    10.4      }
    10.5  }
    10.6  
    10.7 -@synthesize cellClass=_cellClass, rows=_nRows, columns=_nColumns, spacing=_spacing,
    10.8 +@synthesize cellClass=_cellClass, rows=_nRows, columns=_nColumns, spacing=_spacing, reversed=_reversed,
    10.9              usesDiagonals=_usesDiagonals, allowsMoves=_allowsMoves, allowsCaptures=_allowsCaptures;
   10.10  
   10.11  
   10.12 @@ -136,7 +136,7 @@
   10.13                 suggestedFrame: (CGRect)frame
   10.14  {
   10.15      GridCell *cell = [[_cellClass alloc] initWithGrid: self 
   10.16 -                                        row: row column: col
   10.17 +                                                  row: row column: col
   10.18                                                  frame: frame];
   10.19      cell.name = [NSString stringWithFormat: @"%c%u", ('A'+row),(1+col)];
   10.20      return [cell autorelease];
   10.21 @@ -150,7 +150,12 @@
   10.22      unsigned index = row*_nColumns+col;
   10.23      GridCell *cell = [_cells objectAtIndex: index];
   10.24      if( (id)cell == [NSNull null] ) {
   10.25 -        CGRect frame = CGRectMake(col*_spacing.width, row*_spacing.height,
   10.26 +        unsigned effectiveRow=row, effectiveCol=col;
   10.27 +        if( _reversed ) {
   10.28 +            effectiveRow = _nRows-1    - effectiveRow;
   10.29 +            effectiveCol = _nColumns-1 - effectiveCol;
   10.30 +        }
   10.31 +        CGRect frame = CGRectMake(effectiveCol*_spacing.width, effectiveRow*_spacing.height,
   10.32                                    _spacing.width,_spacing.height);
   10.33          cell = [self createCellAtRow: row column: col suggestedFrame: frame];
   10.34          if( cell ) {
   10.35 @@ -274,6 +279,21 @@
   10.36          }
   10.37  }
   10.38  
   10.39 +- (void) drawBackgroundInContext: (CGContextRef)ctx
   10.40 +{
   10.41 +    if( _backgroundImage ) {
   10.42 +        CGRect bounds = self.bounds;
   10.43 +        if( _reversed ) {
   10.44 +            CGContextSaveGState(ctx);
   10.45 +            CGContextRotateCTM(ctx, M_PI);
   10.46 +            CGContextTranslateCTM(ctx, -bounds.size.width, -bounds.size.height);
   10.47 +        }
   10.48 +        CGContextDrawImage(ctx, bounds, _backgroundImage);
   10.49 +        if( _reversed )
   10.50 +            CGContextRestoreGState(ctx);
   10.51 +    }
   10.52 +}
   10.53 +
   10.54  
   10.55  - (void)drawInContext:(CGContextRef)ctx
   10.56  {
   10.57 @@ -281,8 +301,7 @@
   10.58      // in me; this is more efficient than having each cell have its own drawing.
   10.59      [super drawInContext: ctx];
   10.60      
   10.61 -    if( _backgroundImage )
   10.62 -        CGContextDrawImage(ctx, self.bounds, _backgroundImage);
   10.63 +    [self drawBackgroundInContext: ctx];
   10.64      
   10.65      if( _cellColor ) {
   10.66          CGContextSetFillColorWithColor(ctx, _cellColor);
    11.1 --- a/Source/HexchequerGame.m	Tue Jul 08 20:32:52 2008 -0700
    11.2 +++ b/Source/HexchequerGame.m	Wed Jul 09 17:07:45 2008 -0700
    11.3 @@ -42,6 +42,7 @@
    11.4      grid.allowsCaptures = NO;      // no land-on captures, that is
    11.5      grid.cellColor = CreateGray(1.0, 0.25);
    11.6      grid.lineColor = kTranslucentLightGrayColor;
    11.7 +    grid.reversed = ! [[self.players objectAtIndex: 0] isLocal];
    11.8      [grid addCellsInHexagon];
    11.9  }
   11.10  
    12.1 --- a/Source/Turn.h	Tue Jul 08 20:32:52 2008 -0700
    12.2 +++ b/Source/Turn.h	Wed Jul 09 17:07:45 2008 -0700
    12.3 @@ -39,14 +39,14 @@
    12.4  
    12.5  @property (readonly)      Game      *game;
    12.6  @property (readonly)      Player    *player, *nextPlayer;
    12.7 -@property (readonly)      Turn      *previousTurn;
    12.8 +@property (readonly)      Turn      *previousTurn, *nextTurn;
    12.9  @property (readonly)      unsigned   turnNumber;
   12.10  @property (readonly)      BOOL       isLatestTurn;
   12.11  
   12.12  @property                 TurnStatus status;
   12.13  
   12.14 -@property (readonly,copy) NSString  *move;
   12.15 -@property (readonly,copy) NSString  *boardState;
   12.16 +@property (readonly,copy) NSString  *move;              // The player's move (nil for turn  0)
   12.17 +@property (readonly,copy) NSString  *boardState;        // State of the game AFTER the move
   12.18  @property (readonly,retain)NSDate   *date;
   12.19  @property (copy)          NSString  *comment;
   12.20  
    13.1 --- a/Source/Turn.m	Tue Jul 08 20:32:52 2008 -0700
    13.2 +++ b/Source/Turn.m	Wed Jul 09 17:07:45 2008 -0700
    13.3 @@ -99,9 +99,7 @@
    13.4  
    13.5  - (unsigned) turnNumber     {return [_game.turns indexOfObjectIdenticalTo: self];}
    13.6  - (BOOL) isLatestTurn       {return _game.turns.lastObject == self;}
    13.7 -- (Turn*) previousTurn      {return [_game.turns objectAtIndex: self.turnNumber-1];}
    13.8  - (Player*) nextPlayer      {return _player ?_player.nextPlayer :[_game.players objectAtIndex: 0];}
    13.9 -
   13.10  - (TurnStatus) status       {return _status;}
   13.11  
   13.12  - (void) setStatus: (TurnStatus)status
   13.13 @@ -132,6 +130,25 @@
   13.14  }
   13.15  
   13.16  
   13.17 +- (Turn*) previousTurn
   13.18 +{
   13.19 +    unsigned n = self.turnNumber;
   13.20 +    if( n > 0 )
   13.21 +        return [_game.turns objectAtIndex: n-1];
   13.22 +    else
   13.23 +        return nil;
   13.24 +}
   13.25 +
   13.26 +- (Turn*) nextTurn
   13.27 +{
   13.28 +    unsigned n = self.turnNumber;
   13.29 +    if( n+1 < _game.turns.count )
   13.30 +        return [_game.turns objectAtIndex: n+1];
   13.31 +    else
   13.32 +        return nil;
   13.33 +}
   13.34 +
   13.35 +
   13.36  - (void) addToMove: (NSString*)move
   13.37  {
   13.38      if( ! _replaying ) {