Tweaks and fixes, including renaming Game's "board" property/ivar to "table", which is less confusing.
authorJens Alfke <jens@mooseyard.com>
Mon Jul 14 21:00:15 2008 -0700 (2008-07-14)
changeset 1628392c9a969f
parent 15 73f8c889f053
child 17 ccc5ed68222d
Tweaks and fixes, including renaming Game's "board" property/ivar to "table", which is less confusing.
Released as part of Your Move 1.0a2.
GeekGameBoard-iPhone.xcodeproj/project.pbxproj
Source/Bit.h
Source/Bit.m
Source/BitHolder.m
Source/BoardView.h
Source/BoardView.m
Source/CheckersGame.h
Source/CheckersGame.m
Source/DiscPiece.m
Source/GGBLayer.h
Source/GGBLayer.m
Source/GGBUtils.m
Source/Game.h
Source/Game.m
Source/GoGame.h
Source/GoGame.m
Source/HexGrid.m
Source/HexchequerGame.h
Source/HexchequerGame.m
Source/KlondikeGame.m
Source/Player.m
Source/TicTacToeGame.m
Source/Turn.h
Source/Turn.m
Source/iPhoneAppDelegate.m
     1.1 --- a/GeekGameBoard-iPhone.xcodeproj/project.pbxproj	Wed Jul 09 17:07:45 2008 -0700
     1.2 +++ b/GeekGameBoard-iPhone.xcodeproj/project.pbxproj	Mon Jul 14 21:00:15 2008 -0700
     1.3 @@ -11,6 +11,8 @@
     1.4  		1D60589B0D05DD56006BFB54 /* main-iPhone.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main-iPhone.m */; };
     1.5  		1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
     1.6  		1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
     1.7 +		27124B380E2852A700B61BE3 /* Player.m in Sources */ = {isa = PBXBuildFile; fileRef = 27124B350E2852A700B61BE3 /* Player.m */; };
     1.8 +		27124B390E2852A700B61BE3 /* Turn.m in Sources */ = {isa = PBXBuildFile; fileRef = 27124B370E2852A700B61BE3 /* Turn.m */; };
     1.9  		2740502B0DEF36DF0006A9EE /* Pop.aiff in Resources */ = {isa = PBXBuildFile; fileRef = 274050290DEF36DF0006A9EE /* Pop.aiff */; };
    1.10  		2740502C0DEF36DF0006A9EE /* Tink.aiff in Resources */ = {isa = PBXBuildFile; fileRef = 2740502A0DEF36DF0006A9EE /* Tink.aiff */; };
    1.11  		279F4B590D85C51700B32DBF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 279F4B580D85C51700B32DBF /* AudioToolbox.framework */; };
    1.12 @@ -59,6 +61,11 @@
    1.13  		1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
    1.14  		1D6058910D05DD3D006BFB54 /* GeekGameBoard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GeekGameBoard.app; sourceTree = BUILT_PRODUCTS_DIR; };
    1.15  		1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
    1.16 +		27124B330E2852A700B61BE3 /* Game+Protected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Game+Protected.h"; sourceTree = "<group>"; };
    1.17 +		27124B340E2852A700B61BE3 /* Player.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Player.h; sourceTree = "<group>"; };
    1.18 +		27124B350E2852A700B61BE3 /* Player.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Player.m; sourceTree = "<group>"; };
    1.19 +		27124B360E2852A700B61BE3 /* Turn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Turn.h; sourceTree = "<group>"; };
    1.20 +		27124B370E2852A700B61BE3 /* Turn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Turn.m; sourceTree = "<group>"; };
    1.21  		274050290DEF36DF0006A9EE /* Pop.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; name = Pop.aiff; path = /System/Library/Sounds/Pop.aiff; sourceTree = "<absolute>"; };
    1.22  		2740502A0DEF36DF0006A9EE /* Tink.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; name = Tink.aiff; path = /System/Library/Sounds/Tink.aiff; sourceTree = "<absolute>"; };
    1.23  		279F4B580D85C51700B32DBF /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
    1.24 @@ -230,6 +237,11 @@
    1.25  			children = (
    1.26  				27C99AFE0D820868005AFD4F /* Game.h */,
    1.27  				27C99AFF0D820868005AFD4F /* Game.m */,
    1.28 +				27124B330E2852A700B61BE3 /* Game+Protected.h */,
    1.29 +				27124B340E2852A700B61BE3 /* Player.h */,
    1.30 +				27124B350E2852A700B61BE3 /* Player.m */,
    1.31 +				27124B360E2852A700B61BE3 /* Turn.h */,
    1.32 +				27124B370E2852A700B61BE3 /* Turn.m */,
    1.33  				27C99B000D820868005AFD4F /* TicTacToeGame.h */,
    1.34  				27C99B010D820868005AFD4F /* TicTacToeGame.m */,
    1.35  				27C99B020D820868005AFD4F /* CheckersGame.h */,
    1.36 @@ -402,6 +414,8 @@
    1.37  				27C99B510D82106E005AFD4F /* GGBLayer.m in Sources */,
    1.38  				279F4B620D85C63000B32DBF /* GGBTextLayer.m in Sources */,
    1.39  				279F4B6A0D85CBFC00B32DBF /* iPhoneAppDelegate.m in Sources */,
    1.40 +				27124B380E2852A700B61BE3 /* Player.m in Sources */,
    1.41 +				27124B390E2852A700B61BE3 /* Turn.m in Sources */,
    1.42  			);
    1.43  			runOnlyForDeploymentPostprocessing = 0;
    1.44  		};
    1.45 @@ -444,8 +458,8 @@
    1.46  			buildSettings = {
    1.47  				ALWAYS_SEARCH_USER_PATHS = NO;
    1.48  				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
    1.49 -				CODE_SIGN_IDENTITY = "Laurence ANDERSEN";
    1.50 -				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Laurence ANDERSEN";
    1.51 +				CODE_SIGN_IDENTITY = "";
    1.52 +				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Jens Alfke";
    1.53  				GCC_C_LANGUAGE_STANDARD = gnu99;
    1.54  				GCC_TREAT_WARNINGS_AS_ERRORS = YES;
    1.55  				GCC_WARN_ABOUT_RETURN_TYPE = YES;
    1.56 @@ -461,11 +475,12 @@
    1.57  			isa = XCBuildConfiguration;
    1.58  			buildSettings = {
    1.59  				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
    1.60 -				CODE_SIGN_IDENTITY = "Laurence ANDERSEN";
    1.61 -				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Laurence ANDERSEN";
    1.62 +				CODE_SIGN_IDENTITY = "";
    1.63 +				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Jens Alfke";
    1.64  				GCC_C_LANGUAGE_STANDARD = gnu99;
    1.65  				GCC_TREAT_WARNINGS_AS_ERRORS = YES;
    1.66  				GCC_WARN_ABOUT_RETURN_TYPE = YES;
    1.67 +				GCC_WARN_UNUSED_VARIABLE = YES;
    1.68  				PREBINDING = NO;
    1.69  				SDKROOT = iphoneos2.0;
    1.70  				WARNING_CFLAGS = "-Wall";
     2.1 --- a/Source/Bit.h	Wed Jul 09 17:07:45 2008 -0700
     2.2 +++ b/Source/Bit.h	Mon Jul 14 21:00:15 2008 -0700
     2.3 @@ -43,8 +43,10 @@
     2.4  {
     2.5      @private
     2.6      int _restingZ;      // Original z position, saved while pickedUp
     2.7 +#if !TARGET_OS_IPHONE
     2.8      float _restingShadowOpacity, _restingShadowRadius;
     2.9      CGSize _restingShadowOffset;
    2.10 +#endif
    2.11      BOOL _pickedUp;
    2.12      Player *_owner;     // Player that owns this Bit
    2.13      NSInteger _tag;
     3.1 --- a/Source/Bit.m	Wed Jul 09 17:07:45 2008 -0700
     3.2 +++ b/Source/Bit.m	Mon Jul 14 21:00:15 2008 -0700
     3.3 @@ -111,13 +111,17 @@
     3.4              scale = kPickedUpScale;
     3.5              z = kPickedUpZ;
     3.6              _restingZ = self.zPosition;
     3.7 +#if !TARGET_OS_IPHONE
     3.8              _restingShadowOpacity = self.shadowOpacity;
     3.9              _restingShadowOffset  = self.shadowOffset;
    3.10              _restingShadowRadius  = self.shadowRadius;
    3.11 +#endif
    3.12          } else {
    3.13 +#if !TARGET_OS_IPHONE
    3.14              shadow = _restingShadowOpacity;
    3.15              offset = _restingShadowOffset;
    3.16              radius = _restingShadowRadius;
    3.17 +#endif
    3.18              opacity = 1;
    3.19              scale = 1.0/kPickedUpScale;
    3.20              z = _restingZ;
     4.1 --- a/Source/BitHolder.m	Wed Jul 09 17:07:45 2008 -0700
     4.2 +++ b/Source/BitHolder.m	Mon Jul 14 21:00:15 2008 -0700
     4.3 @@ -54,8 +54,6 @@
     4.4          }
     4.5          setObj(&_bit,bit);
     4.6          ChangeSuperlayer(bit,self,-1);
     4.7 -        if( bit )
     4.8 -            NSLog(@"%@: xform = \n%@",bit,StringFromTransform3D(bit.aggregateTransform));//TEMP
     4.9      }
    4.10  }
    4.11  
     5.1 --- a/Source/BoardView.h	Wed Jul 09 17:07:45 2008 -0700
     5.2 +++ b/Source/BoardView.h	Mon Jul 14 21:00:15 2008 -0700
     5.3 @@ -30,7 +30,7 @@
     5.4  {
     5.5      @private
     5.6      Game *_game;                                // Current Game
     5.7 -    GGBLayer *_gameboard;                       // Game's main layer
     5.8 +    GGBLayer *_table;                           // Game's root layer
     5.9      NSSize _oldSize;
    5.10      
    5.11      // Used during mouse-down tracking:
    5.12 @@ -50,7 +50,7 @@
    5.13  }
    5.14  
    5.15  @property (retain) Game *game;
    5.16 -@property (readonly) CALayer *gameboard;
    5.17 +@property (readonly) CALayer *table;
    5.18  
    5.19  - (void) startGameNamed: (NSString*)gameClassName;
    5.20  
     6.1 --- a/Source/BoardView.m	Wed Jul 09 17:07:45 2008 -0700
     6.2 +++ b/Source/BoardView.m	Mon Jul 14 21:00:15 2008 -0700
     6.3 @@ -38,7 +38,7 @@
     6.4  @implementation BoardView
     6.5  
     6.6  
     6.7 -@synthesize gameboard=_gameboard;
     6.8 +@synthesize table=_table;
     6.9  
    6.10  
    6.11  - (void) dealloc
    6.12 @@ -50,24 +50,24 @@
    6.13  
    6.14  - (void) _removeGameBoard
    6.15  {
    6.16 -    if( _gameboard ) {
    6.17 -        RemoveImmediately(_gameboard);
    6.18 -        _gameboard = nil;
    6.19 +    if( _table ) {
    6.20 +        RemoveImmediately(_table);
    6.21 +        _table = nil;
    6.22      }
    6.23  }
    6.24  
    6.25  - (void) createGameBoard
    6.26  {
    6.27      [self _removeGameBoard];
    6.28 -    _gameboard = [[CALayer alloc] init];
    6.29 -    _gameboard.frame = [self gameBoardFrame];
    6.30 -    _gameboard.autoresizingMask = kCALayerMinXMargin | kCALayerMaxXMargin | kCALayerMinYMargin | kCALayerMaxYMargin;
    6.31 +    _table = [[CALayer alloc] init];
    6.32 +    _table.frame = [self gameBoardFrame];
    6.33 +    _table.autoresizingMask = kCALayerMinXMargin | kCALayerMaxXMargin | kCALayerMinYMargin | kCALayerMaxYMargin;
    6.34  
    6.35      // Tell the game to set up the board:
    6.36 -    _game.board = _gameboard;
    6.37 +    _game.table = _table;
    6.38  
    6.39 -    [self.layer addSublayer: _gameboard];
    6.40 -    [_gameboard release];
    6.41 +    [self.layer addSublayer: _table];
    6.42 +    [_table release];
    6.43  }
    6.44  
    6.45  
    6.46 @@ -79,7 +79,7 @@
    6.47  - (void) setGame: (Game*)game
    6.48  {
    6.49      if( game!=_game ) {
    6.50 -        _game.board = nil;
    6.51 +        _game.table = nil;
    6.52          setObj(&_game,game);
    6.53          [self createGameBoard];
    6.54      }
    6.55 @@ -133,9 +133,9 @@
    6.56  {
    6.57      [super setFrameSize: newSize];
    6.58      if( _oldSize.width > 0.0f ) {
    6.59 -        CGAffineTransform xform = _gameboard.affineTransform;
    6.60 +        CGAffineTransform xform = _table.affineTransform;
    6.61          xform.a = xform.d = MIN(newSize.width,newSize.height)/MIN(_oldSize.width,_oldSize.height);
    6.62 -        _gameboard.affineTransform = xform;
    6.63 +        _table.affineTransform = xform;
    6.64      } else
    6.65          [self createGameBoard];
    6.66  }
    6.67 @@ -189,7 +189,7 @@
    6.68                     offset: (CGPoint*)outOffset
    6.69  {
    6.70      CGPoint where = [self _convertPointFromWindowToLayer: locationInWindow ];
    6.71 -    CALayer *layer = [_gameboard hitTest: where];
    6.72 +    CALayer *layer = [_table hitTest: where];
    6.73      while( layer ) {
    6.74          if( match(layer) ) {
    6.75              CGPoint bitPos = [self.layer convertPoint: layer.position 
     7.1 --- a/Source/CheckersGame.h	Wed Jul 09 17:07:45 2008 -0700
     7.2 +++ b/Source/CheckersGame.h	Mon Jul 14 21:00:15 2008 -0700
     7.3 @@ -28,7 +28,7 @@
     7.4      See: http://en.wikipedia.org/wiki/Draughts */
     7.5  @interface CheckersGame : Game 
     7.6  {
     7.7 -    Grid *_grid;
     7.8 +    Grid *_board;
     7.9  }
    7.10  
    7.11  @end
     8.1 --- a/Source/CheckersGame.m	Wed Jul 09 17:07:45 2008 -0700
     8.2 +++ b/Source/CheckersGame.m	Mon Jul 14 21:00:15 2008 -0700
     8.3 @@ -71,7 +71,7 @@
     8.4  - (Piece*) pieceForPlayer: (int)playerNum
     8.5  {
     8.6      Piece *p = [[Piece alloc] init];
     8.7 -    p.bounds = CGRectMake(0,0,floor(_grid.spacing.width),floor(_grid.spacing.height));
     8.8 +    p.bounds = CGRectMake(0,0,floor(_board.spacing.width),floor(_board.spacing.height));
     8.9      p.style = (playerNum ?kPieceStyle2 :kPieceStyle1);
    8.10      p.owner = [self.players objectAtIndex: playerNum];
    8.11      p.name = playerNum ?@"2" :@"1";
    8.12 @@ -87,29 +87,29 @@
    8.13  
    8.14  - (void) setUpBoard
    8.15  {
    8.16 -    RectGrid *grid = [[RectGrid alloc] initWithRows: 8 columns: 8 frame: _board.bounds];
    8.17 -    _grid = grid;
    8.18 -    [_board addSublayer: _grid];
    8.19 -    CGPoint pos = _grid.position;
    8.20 -    pos.x = floor((_board.bounds.size.width-grid.frame.size.width)/2);
    8.21 -    grid.position = pos;
    8.22 -    grid.allowsMoves = YES;
    8.23 -    grid.allowsCaptures = NO;
    8.24 -    grid.cellColor = CreateGray(0.0, 0.25);
    8.25 -    grid.altCellColor = CreateGray(1.0, 0.25);
    8.26 -    grid.lineColor = nil;
    8.27 -    grid.reversed = ! [[self.players objectAtIndex: 0] isLocal];
    8.28 +    RectGrid *board = [[RectGrid alloc] initWithRows: 8 columns: 8 frame: _table.bounds];
    8.29 +    _board = board;
    8.30 +    [_table addSublayer: _board];
    8.31 +    CGPoint pos = _board.position;
    8.32 +    pos.x = floor((_table.bounds.size.width-board.frame.size.width)/2);
    8.33 +    board.position = pos;
    8.34 +    board.allowsMoves = YES;
    8.35 +    board.allowsCaptures = NO;
    8.36 +    board.cellColor    = CreateGray(0.0, 0.5);
    8.37 +    board.altCellColor = CreateGray(1.0, 0.25);
    8.38 +    board.lineColor = nil;
    8.39 +    board.reversed = ! [[self.players objectAtIndex: 0] isLocal];
    8.40  
    8.41      for( int i=0; i<32; i++ ) {
    8.42          int row = i/4;
    8.43 -        [_grid addCellAtRow: row column: 2*(i%4) + (row&1)];
    8.44 +        [_board addCellAtRow: row column: 2*(i%4) + (row&1)];
    8.45      }
    8.46 -    [_grid release]; // its superlayer still retains it
    8.47 +    [_board release]; // its superlayer still retains it
    8.48  }
    8.49  
    8.50  - (NSString*) initialStateString            {return @"111111111111--------222222222222";}
    8.51 -- (NSString*) stateString                   {return _grid.stateString;}
    8.52 -- (void) setStateString: (NSString*)state   {_grid.stateString = state;}
    8.53 +- (NSString*) stateString                   {return _board.stateString;}
    8.54 +- (void) setStateString: (NSString*)state   {_board.stateString = state;}
    8.55  
    8.56  - (Piece*) makePieceNamed: (NSString*)name
    8.57  {
    8.58 @@ -178,7 +178,7 @@
    8.59  
    8.60  - (Player*) checkForWinner
    8.61  {
    8.62 -    NSCountedSet *remaining = _grid.countPiecesByPlayer;
    8.63 +    NSCountedSet *remaining = _board.countPiecesByPlayer;
    8.64      if( remaining.count==1 )
    8.65          return [remaining anyObject];
    8.66      else
    8.67 @@ -192,7 +192,7 @@
    8.68      for( NSString *ident in [move componentsSeparatedByString: @"-"] ) {
    8.69          while( [ident hasSuffix: @"!"] || [ident hasSuffix: @"*"] )
    8.70              ident = [ident substringToIndex: ident.length-1];
    8.71 -        GridCell *dst = [_grid cellWithName: ident];
    8.72 +        GridCell *dst = [_board cellWithName: ident];
    8.73          if( dst == nil )
    8.74              return NO;
    8.75          if( src && ! [self animateMoveFrom: src to: dst] )
     9.1 --- a/Source/DiscPiece.m	Wed Jul 09 17:07:45 2008 -0700
     9.2 +++ b/Source/DiscPiece.m	Mon Jul 14 21:00:15 2008 -0700
     9.3 @@ -41,7 +41,9 @@
     9.4          [_imageLayer release]; // superlayer is holding onto it
     9.5      }
     9.6      _imageLayer.frame = CGRectInset(self.bounds, outerDiameter-diameter, outerDiameter-diameter);
     9.7 +#if !TARGET_OS_IPHONE
     9.8      _imageLayer.cornerRadius = diameter/2;
     9.9 +#endif
    9.10      _imageLayer.contents = (id) image;
    9.11      self.cornerRadius = outerDiameter/2;
    9.12      self.borderWidth = 3;
    10.1 --- a/Source/GGBLayer.h	Wed Jul 09 17:07:45 2008 -0700
    10.2 +++ b/Source/GGBLayer.h	Mon Jul 14 21:00:15 2008 -0700
    10.3 @@ -43,8 +43,6 @@
    10.4      and update every other layer that shares the same style dictionary. */
    10.5  - (void) setValue: (id)value ofStyleProperty: (NSString*)prop;
    10.6  
    10.7 -- (CATransform3D) aggregateTransform;
    10.8 -
    10.9  @end
   10.10  
   10.11  
   10.12 @@ -59,5 +57,3 @@
   10.13  void EndDisableAnimations(void);
   10.14  
   10.15  CGColorRef GetEffectiveBackground( CALayer *layer );
   10.16 -
   10.17 -NSString* StringFromTransform3D( CATransform3D xform );
    11.1 --- a/Source/GGBLayer.m	Wed Jul 09 17:07:45 2008 -0700
    11.2 +++ b/Source/GGBLayer.m	Mon Jul 14 21:00:15 2008 -0700
    11.3 @@ -124,6 +124,7 @@
    11.4  }
    11.5  
    11.6  
    11.7 +#if 0
    11.8  - (CATransform3D) aggregateTransform
    11.9  {
   11.10      CATransform3D xform = CATransform3DIdentity;
   11.11 @@ -146,7 +147,7 @@
   11.12      }
   11.13      return str;
   11.14  }
   11.15 -
   11.16 +#endif
   11.17  
   11.18  
   11.19  #if TARGET_OS_IPHONE
    12.1 --- a/Source/GGBUtils.m	Wed Jul 09 17:07:45 2008 -0700
    12.2 +++ b/Source/GGBUtils.m	Mon Jul 14 21:00:15 2008 -0700
    12.3 @@ -19,10 +19,7 @@
    12.4      THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    12.5  */
    12.6  #import "GGBUtils.h"
    12.7 -
    12.8 -#if TARGET_OS_IPHONE
    12.9  #import <AudioToolbox/AudioToolbox.h>
   12.10 -#endif
   12.11  
   12.12  
   12.13  #ifndef _MYUTILITIES_COLLECTIONUTILS_
   12.14 @@ -54,7 +51,6 @@
   12.15  }    
   12.16  
   12.17  
   12.18 -#if TARGET_OS_IPHONE
   12.19  static SystemSoundID GetSound( NSString *name )
   12.20  {
   12.21      static NSMutableDictionary *sSoundIDs;
   12.22 @@ -64,19 +60,24 @@
   12.23          NSString *type = name.pathExtension;
   12.24          if( ! type.length )
   12.25              type = @"aiff";
   12.26 -        NSString *path = [[NSBundle mainBundle] pathForResource: name.stringByDeletingPathExtension
   12.27 +        name = name.stringByDeletingPathExtension;
   12.28 +        
   12.29 +        NSString *path = [[NSBundle mainBundle] pathForResource: name
   12.30                                                           ofType: type];
   12.31 +#if ! TARGET_OS_IPHONE
   12.32 +        if( ! path )
   12.33 +            path = [@"/System/Library/Sounds" stringByAppendingPathComponent: [name stringByAppendingPathExtension: type]];
   12.34 +#endif
   12.35          NSURL *url;
   12.36          if( path )
   12.37              url = [NSURL fileURLWithPath: path];
   12.38          else {
   12.39 -            NSLog(@"Couldn't find sound %@",name);
   12.40 +            NSLog(@"WARNING: Couldn't find sound %@",name);
   12.41              return 0;
   12.42          }
   12.43 -        //url = [NSURL fileURLWithPath: [@"/Library/Sounds/" stringByAppendingPathComponent: name]];
   12.44          SystemSoundID soundID;
   12.45          if( AudioServicesCreateSystemSoundID((CFURLRef)url,&soundID) != noErr ) {
   12.46 -            NSLog(@"Couldn't load sound %@",url);
   12.47 +            NSLog(@"WARNING: Couldn't load sound %@",url);
   12.48              return 0;
   12.49          }
   12.50          
   12.51 @@ -87,29 +88,17 @@
   12.52      }
   12.53      return [soundIDObj unsignedIntValue];
   12.54  }
   12.55 -#endif
   12.56  
   12.57  
   12.58  void PreloadSound( NSString* name )
   12.59  {
   12.60 -#if TARGET_OS_IPHONE
   12.61 -    GetSound(name);
   12.62 -#else
   12.63 -    NSSound *sound = [[NSSound soundNamed: @"Pop"] copy];
   12.64 -    sound.volume = 0;
   12.65 -    [sound play];
   12.66 -    [sound release];
   12.67 -#endif
   12.68 +    (void) GetSound(name);
   12.69  }    
   12.70  
   12.71  
   12.72  void PlaySound( NSString* name )
   12.73  {
   12.74 -#if TARGET_OS_IPHONE
   12.75      AudioServicesPlaySystemSound( GetSound(name) );
   12.76 -#else
   12.77 -    [[NSSound soundNamed: name] play];
   12.78 -#endif
   12.79  }
   12.80  
   12.81  void Beep()
    13.1 --- a/Source/Game.h	Wed Jul 09 17:07:45 2008 -0700
    13.2 +++ b/Source/Game.h	Mon Jul 14 21:00:15 2008 -0700
    13.3 @@ -29,7 +29,7 @@
    13.4  /** Abstract superclass. Keeps track of the rules and turns of a game. */
    13.5  @interface Game : NSObject <NSCoding>
    13.6  {
    13.7 -    GGBLayer *_board;
    13.8 +    GGBLayer *_table;
    13.9      NSArray *_players;
   13.10      Player *_winner;
   13.11      NSMutableArray *_turns;
   13.12 @@ -55,8 +55,8 @@
   13.13  /** Designated initializer: override this if your subclass needs additional initialization. */
   13.14  - (id) init;
   13.15  
   13.16 -/** Convenience initializer that calls -init, -setBoard:, and -nextTurn. */
   13.17 -- (id) initNewGameWithBoard: (GGBLayer*)board;
   13.18 +/** Convenience initializer that calls -init, -setTable:, and -nextTurn. */
   13.19 +- (id) initNewGameWithTable: (GGBLayer*)table;
   13.20  
   13.21  /** NSCoding initializer. Calls -init, but then restores saved payers, states, moves. */
   13.22  - (id) initWithCoder: (NSCoder*)decoder;
   13.23 @@ -69,7 +69,7 @@
   13.24  @property (readonly) Player *currentPlayer, *winner, *remotePlayer;
   13.25  @property (readonly, getter=isLocal) BOOL local;            // Are all players local?
   13.26  
   13.27 -@property (retain) GGBLayer *board;                         // The root layer for the game.
   13.28 +@property (retain) GGBLayer *table;                         // The root layer for the game.
   13.29  
   13.30  @property (readonly) NSArray *turns;
   13.31  @property (readonly) Turn *currentTurn, *latestTurn;
    14.1 --- a/Source/Game.m	Wed Jul 09 17:07:45 2008 -0700
    14.2 +++ b/Source/Game.m	Mon Jul 14 21:00:15 2008 -0700
    14.3 @@ -68,11 +68,11 @@
    14.4  }
    14.5  
    14.6  
    14.7 -- (id) initNewGameWithBoard: (GGBLayer*)board
    14.8 +- (id) initNewGameWithTable: (GGBLayer*)board
    14.9  {
   14.10      self = [self init];
   14.11      if( self ) {
   14.12 -        self.board = board;
   14.13 +        self.table = board;
   14.14          NSAssert1(_players && _turns, @"%@ failed to set numberOfPlayers",self);
   14.15      }
   14.16      return self;
   14.17 @@ -81,7 +81,7 @@
   14.18  
   14.19  - (void) dealloc
   14.20  {
   14.21 -    [_board release];
   14.22 +    [_table release];
   14.23      [_players release];
   14.24      [_turns release];
   14.25      [_extraValues release];
   14.26 @@ -117,19 +117,19 @@
   14.27      NSAssert1(NO,@"%@ forgot to implement -setUpBoard",[self class]);
   14.28  }
   14.29  
   14.30 -- (GGBLayer*) board
   14.31 +- (GGBLayer*) table
   14.32  {
   14.33 -    return _board;
   14.34 +    return _table;
   14.35  }
   14.36  
   14.37 -- (void) setBoard: (GGBLayer*)board
   14.38 +- (void) setTable: (GGBLayer*)board
   14.39  {
   14.40 -    setObj(&_board,board);
   14.41 +    setObj(&_table,board);
   14.42      if( board ) {
   14.43          // Store a pointer to myself as the value of the "Game" property
   14.44          // of my root layer. (CALayers can have arbitrary KV properties stored into them.)
   14.45          // This is used by the -[CALayer game] category method defined below, to find the Game.
   14.46 -        [_board setValue: self forKey: @"Game"];
   14.47 +        [_table setValue: self forKey: @"Game"];
   14.48          
   14.49          BeginDisableAnimations();
   14.50          
   14.51 @@ -263,7 +263,7 @@
   14.52      if( curTurn.status > kTurnEmpty && curTurn.status < kTurnFinished ) {
   14.53          if( _winner )
   14.54              self.winner = nil;
   14.55 -        if( _board )
   14.56 +        if( _table )
   14.57              self.stateString = curTurn.previousTurn.boardState;
   14.58          curTurn.status = kTurnEmpty;
   14.59      }
   14.60 @@ -308,7 +308,7 @@
   14.61      NSParameterAssert(turnNo<=self.maxTurnNo);
   14.62      unsigned oldTurnNo = _currentTurnNo;
   14.63      if( turnNo != oldTurnNo ) {
   14.64 -        if( _board ) {
   14.65 +        if( _table ) {
   14.66              Turn *turn = [_turns objectAtIndex: turnNo];
   14.67              NSString *state;
   14.68              if( turn.status == kTurnEmpty )
   14.69 @@ -325,7 +325,6 @@
   14.70                      @try{
   14.71                          if( ! [self applyMoveString: move] ) {
   14.72                              _currentTurnNo = oldTurnNo;
   14.73 -                            NSBeep();
   14.74                              NSLog(@"WARNING: %@ failed to apply stored move '%@'!", self,move);
   14.75                              return;
   14.76                          }
   14.77 @@ -341,7 +340,6 @@
   14.78              }
   14.79              if( ! [self.stateString isEqual: state] ) {
   14.80                  _currentTurnNo = oldTurnNo;
   14.81 -                NSBeep();
   14.82                  NSLog(@"WARNING: %@ failed to apply stored state '%@'!", self,state);
   14.83                  return;
   14.84              }
   14.85 @@ -360,7 +358,7 @@
   14.86                || ! [self canBit: bit moveFrom: src to: dst] )
   14.87          return NO;
   14.88      
   14.89 -    ChangeSuperlayer(bit, _board.superlayer, -1);
   14.90 +    ChangeSuperlayer(bit, _table.superlayer, -1);
   14.91      bit.pickedUp = YES;
   14.92      dst.highlighted = YES;
   14.93      [bit performSelector: @selector(setPickedUp:) withObject:nil afterDelay: 0.15];
   14.94 @@ -397,8 +395,8 @@
   14.95          if( oldHolder != dst ) 
   14.96              return [self animateMoveFrom: oldHolder to: dst];
   14.97      } else
   14.98 -        bit.position = [dst convertPoint: GetCGRectCenter(dst.bounds) toLayer: _board.superlayer];
   14.99 -    ChangeSuperlayer(bit, _board.superlayer, -1);
  14.100 +        bit.position = [dst convertPoint: GetCGRectCenter(dst.bounds) toLayer: _table.superlayer];
  14.101 +    ChangeSuperlayer(bit, _table.superlayer, -1);
  14.102      bit.pickedUp = YES;
  14.103      dst.highlighted = YES;
  14.104      
    15.1 --- a/Source/GoGame.h	Wed Jul 09 17:07:45 2008 -0700
    15.2 +++ b/Source/GoGame.h	Mon Jul 14 21:00:15 2008 -0700
    15.3 @@ -28,7 +28,7 @@
    15.4      See: http://en.wikipedia.org/wiki/Go_%28board_game%29 */
    15.5  @interface GoGame : Game
    15.6  {
    15.7 -    RectGrid *_grid;
    15.8 +    RectGrid *_board;
    15.9      Stack *_captured[2];
   15.10  }
   15.11  
    16.1 --- a/Source/GoGame.m	Wed Jul 09 17:07:45 2008 -0700
    16.2 +++ b/Source/GoGame.m	Mon Jul 14 21:00:15 2008 -0700
    16.3 @@ -48,31 +48,31 @@
    16.4  - (void) setUpBoard
    16.5  {
    16.6      int dimensions = [[self class] dimensions];
    16.7 -    CGSize size = _board.bounds.size;
    16.8 +    CGSize size = _table.bounds.size;
    16.9      CGFloat boardSide = MIN(size.width,size.height);
   16.10 -    RectGrid *grid = [[RectGrid alloc] initWithRows: dimensions columns: dimensions 
   16.11 +    RectGrid *board = [[RectGrid alloc] initWithRows: dimensions columns: dimensions 
   16.12                                                frame: CGRectMake(floor((size.width-boardSide)/2),
   16.13                                                                  floor((size.height-boardSide)/2),
   16.14                                                                  boardSide,boardSide)];
   16.15 -    _grid = grid;
   16.16 +    _board = board;
   16.17      /*
   16.18      grid.backgroundColor = GetCGPatternNamed(@"Wood.jpg");
   16.19      grid.borderColor = kTranslucentLightGrayColor;
   16.20      grid.borderWidth = 2;
   16.21      */
   16.22 -    grid.lineColor = kTranslucentGrayColor;
   16.23 -    grid.cellClass = [GoSquare class];
   16.24 -    [grid addAllCells];
   16.25 -    ((GoSquare*)[grid cellAtRow: 2 column: 2]).dotted = YES;
   16.26 -    ((GoSquare*)[grid cellAtRow: 6 column: 6]).dotted = YES;
   16.27 -    ((GoSquare*)[grid cellAtRow: 2 column: 6]).dotted = YES;
   16.28 -    ((GoSquare*)[grid cellAtRow: 6 column: 2]).dotted = YES;
   16.29 -    grid.usesDiagonals = grid.allowsMoves = grid.allowsCaptures = NO;
   16.30 -    [_board addSublayer: grid];
   16.31 -    [grid release];
   16.32 +    board.lineColor = kTranslucentGrayColor;
   16.33 +    board.cellClass = [GoSquare class];
   16.34 +    [board addAllCells];
   16.35 +    ((GoSquare*)[board cellAtRow: 2 column: 2]).dotted = YES;
   16.36 +    ((GoSquare*)[board cellAtRow: 6 column: 6]).dotted = YES;
   16.37 +    ((GoSquare*)[board cellAtRow: 2 column: 6]).dotted = YES;
   16.38 +    ((GoSquare*)[board cellAtRow: 6 column: 2]).dotted = YES;
   16.39 +    board.usesDiagonals = board.allowsMoves = board.allowsCaptures = NO;
   16.40 +    [_table addSublayer: board];
   16.41 +    [board release];
   16.42      
   16.43 -    CGRect gridFrame = grid.frame;
   16.44 -    CGFloat pieceSize = (int)grid.spacing.width & ~1;  // make sure it's even
   16.45 +    CGRect gridFrame = board.frame;
   16.46 +    CGFloat pieceSize = (int)board.spacing.width & ~1;  // make sure it's even
   16.47      CGFloat captureHeight = gridFrame.size.height-4*pieceSize;
   16.48      _captured[0] = [[Stack alloc] initWithStartPos: CGPointMake(2*pieceSize,0)
   16.49                                             spacing: CGSizeMake(0,pieceSize)
   16.50 @@ -82,7 +82,7 @@
   16.51                                        CGRectGetMinY(gridFrame)+3*pieceSize,
   16.52                                        2*pieceSize, captureHeight);
   16.53      _captured[0].zPosition = kPieceZ+1;
   16.54 -    [_board addSublayer: _captured[0]];
   16.55 +    [_table addSublayer: _captured[0]];
   16.56      [_captured[0] release];
   16.57      
   16.58      _captured[1] = [[Stack alloc] initWithStartPos: CGPointMake(0,captureHeight)
   16.59 @@ -93,7 +93,7 @@
   16.60                                        CGRectGetMinY(gridFrame)+pieceSize,
   16.61                                        2*pieceSize, captureHeight);
   16.62      _captured[1].zPosition = kPieceZ+1;
   16.63 -    [_board addSublayer: _captured[1]];
   16.64 +    [_table addSublayer: _captured[1]];
   16.65      [_captured[1] release];
   16.66  
   16.67      PreloadSound(@"Pop");
   16.68 @@ -107,7 +107,7 @@
   16.69  - (Piece*) pieceForPlayer: (int)index
   16.70  {
   16.71      NSString *imageName = index ?@"bot086.png" :@"bot089.png";
   16.72 -    CGFloat pieceSize = (int)(_grid.spacing.width * 0.9) & ~1;  // make sure it's even
   16.73 +    CGFloat pieceSize = (int)(_board.spacing.width * 0.9) & ~1;  // make sure it's even
   16.74      Piece *stone = [[Piece alloc] initWithImageNamed: imageName scale: pieceSize];
   16.75      stone.owner = [self.players objectAtIndex: index];
   16.76      return [stone autorelease];
   16.77 @@ -191,11 +191,11 @@
   16.78  
   16.79  - (NSString*) stateString
   16.80  {
   16.81 -    int n = _grid.rows;
   16.82 +    int n = _board.rows;
   16.83      unichar state[n*n];
   16.84      for( int y=0; y<n; y++ )
   16.85          for( int x=0; x<n; x++ ) {
   16.86 -            Bit *bit = [_grid cellAtRow: y column: x].bit;
   16.87 +            Bit *bit = [_board cellAtRow: y column: x].bit;
   16.88              unichar ch;
   16.89              if( bit==nil )
   16.90                  ch = '-';
   16.91 @@ -209,7 +209,7 @@
   16.92  - (void) setStateString: (NSString*)state
   16.93  {
   16.94      NSLog(@"Go: setStateString: '%@'",state);
   16.95 -    int n = _grid.rows;
   16.96 +    int n = _board.rows;
   16.97      for( int y=0; y<n; y++ )
   16.98          for( int x=0; x<n; x++ ) {
   16.99              int i = y*n+x;
  16.100 @@ -219,7 +219,7 @@
  16.101                  if( index==0 || index==1 )
  16.102                      piece = [self pieceForPlayer: index];
  16.103              }
  16.104 -            [_grid cellAtRow: y column: x].bit = piece;
  16.105 +            [_board cellAtRow: y column: x].bit = piece;
  16.106          }
  16.107  }
  16.108  
  16.109 @@ -227,7 +227,7 @@
  16.110  - (BOOL) applyMoveString: (NSString*)move
  16.111  {
  16.112      NSLog(@"Go: applyMoveString: '%@'",move);
  16.113 -    return [self animatePlacementIn: [_grid cellWithName: move]];
  16.114 +    return [self animatePlacementIn: [_board cellWithName: move]];
  16.115  }
  16.116  
  16.117  
    17.1 --- a/Source/HexGrid.m	Wed Jul 09 17:07:45 2008 -0700
    17.2 +++ b/Source/HexGrid.m	Mon Jul 14 21:00:15 2008 -0700
    17.3 @@ -100,7 +100,10 @@
    17.4                 suggestedFrame: (CGRect)frame
    17.5  {
    17.6      // Overridden to stagger the odd-numbered rows
    17.7 -    if( row & 1 )
    17.8 +    BOOL stagger = (row & 1) != 0;
    17.9 +    if( _reversed && (_nRows & 1) )
   17.10 +        stagger = !stagger;
   17.11 +    if( stagger )
   17.12          frame.origin.x += _spacing.width/2;
   17.13      frame.size.height += _capHeight;
   17.14      return [super createCellAtRow: row column: col suggestedFrame: frame];
    18.1 --- a/Source/HexchequerGame.h	Wed Jul 09 17:07:45 2008 -0700
    18.2 +++ b/Source/HexchequerGame.h	Mon Jul 14 21:00:15 2008 -0700
    18.3 @@ -23,10 +23,9 @@
    18.4  #import "CheckersGame.h"
    18.5  
    18.6  /** A hex-grid variant of checkers, made up on a whim to test out hex boards.
    18.7 -    A much better existing hexagonal checkers is HexDame --
    18.8 -    see: http://www.mindsports.net/CompleteGames/Elimination/HexDame.html 
    18.9 -    Its implementation is left as an exercise for the reader.
   18.10 -    Hint: rotate the HexGrid 30 degrees! */
   18.11 +    It's a direct translation of the US checkers rules to the hex grid, inspired
   18.12 +    Christian Freeling's HexDame, which is based on International Checkers.
   18.13 +    [see: http://www.mindsports.net/CompleteGames/Elimination/HexDame.html] */
   18.14  @interface HexchequerGame : CheckersGame 
   18.15  
   18.16  @end
    19.1 --- a/Source/HexchequerGame.m	Wed Jul 09 17:07:45 2008 -0700
    19.2 +++ b/Source/HexchequerGame.m	Mon Jul 14 21:00:15 2008 -0700
    19.3 @@ -32,24 +32,27 @@
    19.4  
    19.5  - (void) setUpBoard
    19.6  {
    19.7 -    HexGrid *grid = [[HexGrid alloc] initWithRows: 9 columns: 9 frame: _board.bounds];
    19.8 -    _grid = grid;
    19.9 -    [_board addSublayer: _grid];
   19.10 -    CGPoint pos = grid.position;
   19.11 -    pos.x += grid.spacing.width / 4;    // The right edge of the grid is blank because of the unused cells outside the hexagon
   19.12 -    grid.position = pos;
   19.13 -    grid.allowsMoves = YES;
   19.14 -    grid.allowsCaptures = NO;      // no land-on captures, that is
   19.15 -    grid.cellColor = CreateGray(1.0, 0.25);
   19.16 -    grid.lineColor = kTranslucentLightGrayColor;
   19.17 -    grid.reversed = ! [[self.players objectAtIndex: 0] isLocal];
   19.18 -    [grid addCellsInHexagon];
   19.19 +    // Create a hex grid and rotate it 30 degrees so the cells are edge-up:
   19.20 +    CGRect tableBounds = _table.bounds;
   19.21 +    CGFloat s = tableBounds.size.height / 9;
   19.22 +    HexGrid *board = [[HexGrid alloc] initWithRows: 9 columns: 9
   19.23 +                                           spacing: CGSizeMake(s,s)
   19.24 +                                          position: GetCGRectCenter(tableBounds)];
   19.25 +    board.anchorPoint = CGPointMake(0.47,0.5);  // Missing half-cells on right edge perturb center pt
   19.26 +    [board setValue: [NSNumber numberWithDouble: M_PI/6] forKeyPath: @"transform.rotation"];
   19.27 +    _board = board;
   19.28 +    [_table addSublayer: _board];
   19.29 +    board.allowsMoves = YES;
   19.30 +    board.allowsCaptures = NO;      // no land-on captures, that is
   19.31 +    board.cellColor = CreateGray(1.0, 0.25);
   19.32 +    board.lineColor = kTranslucentLightGrayColor;
   19.33 +    board.reversed = ! [[self.players objectAtIndex: 0] isLocal];
   19.34 +    [board addCellsInHexagon];
   19.35  }
   19.36  
   19.37 -
   19.38  - (NSString*) initialStateString
   19.39  {
   19.40 -    return @"111111111111111111-------------------------222222222222222222";
   19.41 +      return @"1111-1111--1111---1111-----------------2222---2222--2222-2222";
   19.42  }
   19.43  
   19.44  
   19.45 @@ -57,18 +60,19 @@
   19.46  {
   19.47      Hex *src=(Hex*)srcHolder, *dst=(Hex*)dstHolder;
   19.48      if( [bit valueForKey: @"King"] )
   19.49 -        if( dst==src.bl || dst==src.br || dst==src.l || dst==src.r
   19.50 +        if( dst==src.bl || dst==src.br || dst==src.l
   19.51             || (src.bl.bit.unfriendly && dst==src.bl.bl) || (src.br.bit.unfriendly && dst==src.br.br)
   19.52 -           || (src.l.bit.unfriendly  && dst==src.l.l)   || (src.r.bit.unfriendly  && dst==src.r.r) )
   19.53 +           || (src.l.bit.unfriendly  && dst==src.l.l) )
   19.54              return YES;    
   19.55 -    return dst==src.fl || dst==src.fr
   19.56 -        || (src.fl.bit.unfriendly && dst==src.fl.fl) || (src.fr.bit.unfriendly && dst==src.fr.fr);
   19.57 +    return dst==src.fl || dst==src.fr || dst==src.r
   19.58 +            || (src.fl.bit.unfriendly && dst==src.fl.fl) 
   19.59 +            || (src.fr.bit.unfriendly && dst==src.fr.fr) 
   19.60 +            || (src. r.bit.unfriendly && dst==src. r. r);
   19.61  }
   19.62  
   19.63  - (void) bit: (Bit*)bit movedFrom: (id<BitHolder>)srcHolder to: (id<BitHolder>)dstHolder
   19.64  {
   19.65      Hex *src=(Hex*)srcHolder, *dst=(Hex*)dstHolder;
   19.66 -    int playerIndex = self.currentPlayer.index;
   19.67  
   19.68      Turn *turn = self.currentTurn;
   19.69      if( turn.move.length==0 )
   19.70 @@ -80,7 +84,7 @@
   19.71      PlaySound(isKing ?@"Funk" :@"Tink");
   19.72  
   19.73      // "King" a piece that made it to the last row:
   19.74 -    if( dst.row == (playerIndex ?0 :8) )
   19.75 +    if( dst.fr == nil )
   19.76          if( ! isKing ) {
   19.77              PlaySound(@"Blow");
   19.78              bit.scale = 1.4;
   19.79 @@ -109,11 +113,14 @@
   19.80          [capture destroyBit];
   19.81          
   19.82          // Now check if another capture is possible. If so, don't end the turn:
   19.83 -        if( (dst.fl.bit.unfriendly && dst.fl.fl.empty) || (dst.fr.bit.unfriendly && dst.fr.fr.empty) )
   19.84 +        if( (dst.fl.bit.unfriendly && dst.fl.fl.empty) 
   19.85 +                || (dst.fr.bit.unfriendly && dst.fr.fr.empty) 
   19.86 +                || (dst. r.bit.unfriendly && dst. r. r.empty) )
   19.87              return;
   19.88          if( isKing )
   19.89 -            if( (dst.bl.bit.unfriendly && dst.bl.bl.empty) || (dst.br.bit.unfriendly && dst.br.br.empty)
   19.90 -                    || (dst.l.bit.unfriendly && dst.l.l.empty) || (dst.r.bit.unfriendly && dst.r.r.empty))
   19.91 +            if( (dst.bl.bit.unfriendly && dst.bl.bl.empty)
   19.92 +                    || (dst.br.bit.unfriendly && dst.br.br.empty)
   19.93 +                    || (dst.l.bit.unfriendly && dst.l.l.empty) )
   19.94                  return;
   19.95      }
   19.96      
    20.1 --- a/Source/KlondikeGame.m	Wed Jul 09 17:07:45 2008 -0700
    20.2 +++ b/Source/KlondikeGame.m	Mon Jul 14 21:00:15 2008 -0700
    20.3 @@ -50,7 +50,7 @@
    20.4          
    20.5  - (void) setUpBoard
    20.6  {
    20.7 -    CGSize boardSize = _board.bounds.size;
    20.8 +    CGSize boardSize = _table.bounds.size;
    20.9      CGFloat xSpacing = floor(boardSize.width/7);
   20.10      CGSize kCardSize;
   20.11      kCardSize.width  = round(xSpacing * 0.9);  // 1/7th of width, with 10% gap
   20.12 @@ -62,19 +62,19 @@
   20.13      _deck = [[[Deck alloc] initWithCardsOfClass: [PlayingCard class]] autorelease];
   20.14      [_deck shuffle];
   20.15      _deck.position = pos;
   20.16 -    [_board addSublayer: _deck];
   20.17 +    [_table addSublayer: _deck];
   20.18      
   20.19      pos.x += xSpacing;
   20.20      _sink = [[[Deck alloc] init] autorelease];
   20.21      _sink.position = pos;
   20.22 -    [_board addSublayer: _sink];
   20.23 +    [_table addSublayer: _sink];
   20.24      
   20.25      pos.x += xSpacing;
   20.26      for( CardSuit suit=kSuitClubs; suit<=kSuitSpades; suit++ ) {
   20.27          pos.x += xSpacing;
   20.28          Deck *aces = [[[Deck alloc] init] autorelease];
   20.29          aces.position = pos;
   20.30 -        [_board addSublayer: aces];
   20.31 +        [_table addSublayer: aces];
   20.32          _aces[suit] = aces;
   20.33      }
   20.34      
   20.35 @@ -88,7 +88,7 @@
   20.36          stackFrame.origin.x += xSpacing;
   20.37          stack.backgroundColor = nil; //kAlmostInvisibleWhiteColor;
   20.38          stack.dragAsStacks = YES;
   20.39 -        [_board addSublayer: stack];
   20.40 +        [_table addSublayer: stack];
   20.41          
   20.42          // According to the rules, one card should be added to each stack in turn, instead
   20.43          // of populating entire stacks one at a time. However, if one trusts the Deck's
    21.1 --- a/Source/Player.m	Wed Jul 09 17:07:45 2008 -0700
    21.2 +++ b/Source/Player.m	Mon Jul 14 21:00:15 2008 -0700
    21.3 @@ -8,6 +8,7 @@
    21.4  
    21.5  #import "Player.h"
    21.6  #import "Game.h"
    21.7 +#import "GGBUtils.h"
    21.8  
    21.9  
   21.10  #pragma mark -
    22.1 --- a/Source/TicTacToeGame.m	Wed Jul 09 17:07:45 2008 -0700
    22.2 +++ b/Source/TicTacToeGame.m	Mon Jul 14 21:00:15 2008 -0700
    22.3 @@ -50,19 +50,19 @@
    22.4  - (void) setUpBoard
    22.5  {
    22.6      // Create a 3x3 grid:
    22.7 -    CGFloat center = floor(CGRectGetMidX(_board.bounds));
    22.8 +    CGFloat center = floor(CGRectGetMidX(_table.bounds));
    22.9      [_grid release];
   22.10      _grid = [[RectGrid alloc] initWithRows: 3 columns: 3 frame: CGRectMake(center-150,0, 300,300)];
   22.11      [_grid addAllCells];
   22.12      _grid.allowsMoves = _grid.allowsCaptures = NO;
   22.13      _grid.cellColor = CreateGray(1.0, 0.25);
   22.14      _grid.lineColor = kTranslucentLightGrayColor;
   22.15 -    [_board addSublayer: _grid];
   22.16 +    [_table addSublayer: _grid];
   22.17      
   22.18      // Create piece dispensers for the two players:
   22.19      for( int playerNumber=0; playerNumber<=1; playerNumber++ ) {
   22.20          Piece *p = [self pieceForPlayer: playerNumber];
   22.21 -        CGFloat x = floor(CGRectGetMidX(_board.bounds));
   22.22 +        CGFloat x = floor(CGRectGetMidX(_table.bounds));
   22.23  #if TARGET_OS_IPHONE
   22.24          x = x - 80 + 160*playerNumber;
   22.25          CGFloat y = 360;
   22.26 @@ -73,7 +73,7 @@
   22.27          [_dispenser[playerNumber] release];
   22.28          _dispenser[playerNumber] = [[Dispenser alloc] initWithPrototype: p quantity: 0
   22.29                                                                    frame: CGRectMake(x-45,y-45, 90,90)];
   22.30 -        [_board addSublayer: _dispenser[playerNumber]];
   22.31 +        [_table addSublayer: _dispenser[playerNumber]];
   22.32      }            
   22.33  }
   22.34  
    23.1 --- a/Source/Turn.h	Wed Jul 09 17:07:45 2008 -0700
    23.2 +++ b/Source/Turn.h	Mon Jul 14 21:00:15 2008 -0700
    23.3 @@ -58,4 +58,9 @@
    23.4  
    23.5  @property BOOL replaying;
    23.6  
    23.7 +
    23.8 +
    23.9 +/** Changes a Turn's status from finished back to complete. For use only by -[Game unfinishLastTurn] */
   23.10 +- (void) _unfinish;
   23.11 +
   23.12  @end
    24.1 --- a/Source/Turn.m	Wed Jul 09 17:07:45 2008 -0700
    24.2 +++ b/Source/Turn.m	Mon Jul 14 21:00:15 2008 -0700
    24.3 @@ -130,6 +130,15 @@
    24.4  }
    24.5  
    24.6  
    24.7 +- (void) _unfinish
    24.8 +{
    24.9 +    NSAssert(_status==kTurnFinished,@"Turn must be finished");
   24.10 +    [self willChangeValueForKey: @"status"];
   24.11 +    _status = kTurnComplete;
   24.12 +    [self didChangeValueForKey: @"status"];
   24.13 +}
   24.14 +
   24.15 +
   24.16  - (Turn*) previousTurn
   24.17  {
   24.18      unsigned n = self.turnNumber;
   24.19 @@ -169,7 +178,7 @@
   24.20  {
   24.21      if( ! _replaying ) {
   24.22          NSAssert(_status<kTurnFinished,@"Finished Turn can't be modified");
   24.23 -        if( _game.board )
   24.24 +        if( _game.table )
   24.25              self.boardState = _game.stateString;
   24.26      }
   24.27  }
    25.1 --- a/Source/iPhoneAppDelegate.m	Wed Jul 09 17:07:45 2008 -0700
    25.2 +++ b/Source/iPhoneAppDelegate.m	Mon Jul 14 21:00:15 2008 -0700
    25.3 @@ -9,10 +9,12 @@
    25.4  #import "iPhoneAppDelegate.h"
    25.5  #import "BoardUIView.h"
    25.6  #import "Game.h"
    25.7 +#import "Player.h"
    25.8  #import "QuartzUtils.h"
    25.9  #import "GGBUtils.h"
   25.10  
   25.11  
   25.12 +#if 0
   25.13  // Temporary HACK to fix logging problem in beta 6 iPhone OS
   25.14  extern void _NSSetLogCStringFunction(void (*)(const char *string, unsigned length, BOOL withSyslogBanner));
   25.15  static void PrintNSLogMessage(const char *string, unsigned length, BOOL withSyslogBanner)
   25.16 @@ -24,6 +26,7 @@
   25.17  {
   25.18  	_NSSetLogCStringFunction(PrintNSLogMessage);
   25.19  }
   25.20 +#endif
   25.21  
   25.22  
   25.23  @implementation GGB_iPhoneAppDelegate