* Added API to Stack for removing bits.
authorJens Alfke <jens@mooseyard.com>
Mon Jul 21 17:32:21 2008 -0700 (2008-07-21)
changeset 212eb229411d73
parent 20 7c9ecb09a612
child 22 4cb50131788f
* Added API to Stack for removing bits.
* GoGame correctly saves/restores number of captured pieces.
* Improved positioning of captured-piece Stacks in GoGame.
* New Go piece icons.
* Added "Warn" function to GGBUtils.
Resources/Stone-black.png
Resources/Stone-black.psd
Resources/Stone-white.png
Resources/Stone-white.psd
Source/GGBUtils.h
Source/GGBUtils.m
Source/Game.m
Source/GoGame.m
Source/QuartzUtils.m
Source/Stack.h
Source/Stack.m
     1.1 Binary file Resources/Stone-black.png has changed
     2.1 Binary file Resources/Stone-black.psd has changed
     3.1 Binary file Resources/Stone-white.png has changed
     4.1 Binary file Resources/Stone-white.psd has changed
     5.1 --- a/Source/GGBUtils.h	Fri Jul 18 13:26:59 2008 -0700
     5.2 +++ b/Source/GGBUtils.h	Mon Jul 21 17:32:21 2008 -0700
     5.3 @@ -20,6 +20,11 @@
     5.4  */
     5.5  
     5.6  
     5.7 +#ifndef Warn
     5.8 +#define Warn(MSG,...) NSLog(@"WARNING: " #MSG,__VA_ARGS__)
     5.9 +#endif
    5.10 +
    5.11 +
    5.12  /** Handy utility for assigning a new value to a retained instance variable. Use as:
    5.13          setObj(&_instanceVar, newValue);
    5.14      It releases the old value and retains the new one. */
     6.1 --- a/Source/GGBUtils.m	Fri Jul 18 13:26:59 2008 -0700
     6.2 +++ b/Source/GGBUtils.m	Mon Jul 21 17:32:21 2008 -0700
     6.3 @@ -72,12 +72,12 @@
     6.4          if( path )
     6.5              url = [NSURL fileURLWithPath: path];
     6.6          else {
     6.7 -            NSLog(@"WARNING: Couldn't find sound %@",name);
     6.8 +            Warn(@"Couldn't find sound %@",name);
     6.9              return 0;
    6.10          }
    6.11          SystemSoundID soundID;
    6.12          if( AudioServicesCreateSystemSoundID((CFURLRef)url,&soundID) != noErr ) {
    6.13 -            NSLog(@"WARNING: Couldn't load sound %@",url);
    6.14 +            Warn(@"Couldn't load sound %@",url);
    6.15              return 0;
    6.16          }
    6.17          
     7.1 --- a/Source/Game.m	Fri Jul 18 13:26:59 2008 -0700
     7.2 +++ b/Source/Game.m	Mon Jul 21 17:32:21 2008 -0700
     7.3 @@ -325,7 +325,7 @@
     7.4                      @try{
     7.5                          if( ! [self applyMoveString: move] ) {
     7.6                              _currentTurnNo = oldTurnNo;
     7.7 -                            NSLog(@"WARNING: %@ failed to apply stored move '%@'!", self,move);
     7.8 +                            Warn(@"%@ failed to apply stored move '%@'!", self,move);
     7.9                              return;
    7.10                          }
    7.11                      }@finally{
    7.12 @@ -340,7 +340,7 @@
    7.13              }
    7.14              if( ! [self.stateString isEqual: state] ) {
    7.15                  _currentTurnNo = oldTurnNo;
    7.16 -                NSLog(@"WARNING: %@ failed to apply stored state '%@'!", self,state);
    7.17 +                Warn(@"%@ failed to apply stored state '%@'!", self,state);
    7.18                  return;
    7.19              }
    7.20          } else
     8.1 --- a/Source/GoGame.m	Fri Jul 18 13:26:59 2008 -0700
     8.2 +++ b/Source/GoGame.m	Mon Jul 21 17:32:21 2008 -0700
     8.3 @@ -39,7 +39,7 @@
     8.4      self = [super init];
     8.5      if (self != nil) {
     8.6          [self setNumberOfPlayers: 2];
     8.7 -        [(Player*)[_players objectAtIndex: 0] setName: @"Red"];
     8.8 +        [(Player*)[_players objectAtIndex: 0] setName: @"Black"];
     8.9          [(Player*)[_players objectAtIndex: 1] setName: @"White"];
    8.10      }
    8.11      return self;
    8.12 @@ -48,8 +48,9 @@
    8.13  - (void) setUpBoard
    8.14  {
    8.15      int dimensions = [[self class] dimensions];
    8.16 -    CGSize size = _table.bounds.size;
    8.17 -    CGFloat boardSide = MIN(size.width,size.height);
    8.18 +    CGRect tableBounds = _table.bounds;
    8.19 +    CGSize size = tableBounds.size;
    8.20 +    CGFloat boardSide = MIN(size.width* dimensions/(CGFloat)(dimensions+2),size.height);
    8.21      RectGrid *board = [[RectGrid alloc] initWithRows: dimensions columns: dimensions 
    8.22                                                frame: CGRectMake(floor((size.width-boardSide)/2),
    8.23                                                                  floor((size.height-boardSide)/2),
    8.24 @@ -73,25 +74,29 @@
    8.25      
    8.26      CGRect gridFrame = board.frame;
    8.27      CGFloat pieceSize = (int)board.spacing.width & ~1;  // make sure it's even
    8.28 -    CGFloat captureHeight = gridFrame.size.height-4*pieceSize;
    8.29 -    _captured[0] = [[Stack alloc] initWithStartPos: CGPointMake(2*pieceSize,0)
    8.30 +    CGFloat captureMinY = CGRectGetMinY(tableBounds) + pieceSize/2,
    8.31 +            captureHeight = size.height - pieceSize;
    8.32 +    _captured[0] = [[Stack alloc] initWithStartPos: CGPointMake(pieceSize/2,0)
    8.33                                             spacing: CGSizeMake(0,pieceSize)
    8.34                                        wrapInterval: floor(captureHeight/pieceSize)
    8.35 -                                       wrapSpacing: CGSizeMake(-pieceSize,0)];
    8.36 -    _captured[0].frame = CGRectMake(CGRectGetMinX(gridFrame)-3*pieceSize, 
    8.37 -                                      CGRectGetMinY(gridFrame)+3*pieceSize,
    8.38 -                                      2*pieceSize, captureHeight);
    8.39 +                                       wrapSpacing: CGSizeMake(pieceSize,0)];
    8.40 +    _captured[0].frame = CGRectMake(CGRectGetMinX(tableBounds), 
    8.41 +                                    captureMinY,
    8.42 +                                    CGRectGetMinX(gridFrame)-CGRectGetMinX(tableBounds),
    8.43 +                                    captureHeight);
    8.44      _captured[0].zPosition = kPieceZ+1;
    8.45      [_table addSublayer: _captured[0]];
    8.46      [_captured[0] release];
    8.47      
    8.48 -    _captured[1] = [[Stack alloc] initWithStartPos: CGPointMake(0,captureHeight)
    8.49 +    _captured[1] = [[Stack alloc] initWithStartPos: CGPointMake(pieceSize/2,captureHeight)
    8.50                                             spacing: CGSizeMake(0,-pieceSize)
    8.51                                        wrapInterval: floor(captureHeight/pieceSize)
    8.52 -                                       wrapSpacing: CGSizeMake(pieceSize,0)];
    8.53 -    _captured[1].frame = CGRectMake(CGRectGetMaxX(gridFrame)+pieceSize, 
    8.54 -                                      CGRectGetMinY(gridFrame)+pieceSize,
    8.55 -                                      2*pieceSize, captureHeight);
    8.56 +                                       wrapSpacing: CGSizeMake(-pieceSize,0)];
    8.57 +    _captured[1].frame = CGRectMake(CGRectGetMaxX(gridFrame), 
    8.58 +                                    captureMinY,
    8.59 +                                    CGRectGetMaxX(tableBounds)-CGRectGetMaxX(gridFrame),
    8.60 +                                    captureHeight);
    8.61 +    _captured[1].startPos = CGPointMake(CGRectGetMaxX(_captured[1].bounds)-pieceSize/2, captureHeight);
    8.62      _captured[1].zPosition = kPieceZ+1;
    8.63      [_table addSublayer: _captured[1]];
    8.64      [_captured[1] release];
    8.65 @@ -101,13 +106,13 @@
    8.66  
    8.67  - (CGImageRef) iconForPlayer: (int)playerNum
    8.68  {
    8.69 -    return GetCGImageNamed( playerNum ?@"bot086.png" :@"bot089.png" );
    8.70 +    return GetCGImageNamed( playerNum ?@"Stone-white.png" :@"Stone-black.png" );
    8.71  }
    8.72  
    8.73  - (Piece*) pieceForPlayer: (int)index
    8.74  {
    8.75 -    NSString *imageName = index ?@"bot086.png" :@"bot089.png";
    8.76 -    CGFloat pieceSize = (int)(_board.spacing.width * 0.9) & ~1;  // make sure it's even
    8.77 +    NSString *imageName = index ?@"Stone-white.png" :@"Stone-black.png";
    8.78 +    CGFloat pieceSize = (int)(_board.spacing.width * 1.8) & ~1;  // make sure it's even
    8.79      Piece *stone = [[Piece alloc] initWithImageNamed: imageName scale: pieceSize];
    8.80      stone.owner = [self.players objectAtIndex: index];
    8.81      return [stone autorelease];
    8.82 @@ -203,12 +208,19 @@
    8.83                  ch = '1' + bit.owner.index;
    8.84              state[y*n+x] = ch;
    8.85          }
    8.86 -    return [NSString stringWithCharacters: state length: n*n];
    8.87 +    NSMutableString *stateString = [NSMutableString stringWithCharacters: state length: n*n];
    8.88 +    
    8.89 +    NSUInteger cap0=_captured[0].numberOfBits, cap1=_captured[1].numberOfBits;
    8.90 +    if( cap0 || cap1 )
    8.91 +        [stateString appendFormat: @",%i,%i", cap0,cap1];
    8.92 +    return stateString;
    8.93  }
    8.94  
    8.95  - (void) setStateString: (NSString*)state
    8.96  {
    8.97 -    NSLog(@"Go: setStateString: '%@'",state);
    8.98 +    //NSLog(@"Go: setStateString: '%@'",state);
    8.99 +    NSArray *components = [state componentsSeparatedByString: @","];
   8.100 +    state = [components objectAtIndex: 0];
   8.101      int n = _board.rows;
   8.102      for( int y=0; y<n; y++ )
   8.103          for( int x=0; x<n; x++ ) {
   8.104 @@ -221,12 +233,24 @@
   8.105              }
   8.106              [_board cellAtRow: y column: x].bit = piece;
   8.107          }
   8.108 +    
   8.109 +    if( components.count < 3 )
   8.110 +        components = nil;
   8.111 +    for( int player=0; player<=1; player++ ) {
   8.112 +        NSUInteger nCaptured = [[components objectAtIndex: 1+player] intValue];
   8.113 +        NSUInteger curNCaptured = _captured[player].numberOfBits;
   8.114 +        if( nCaptured < curNCaptured )
   8.115 +           _captured[player].numberOfBits = nCaptured;
   8.116 +        else
   8.117 +            for( int i=curNCaptured; i<nCaptured; i++ )
   8.118 +                [_captured[player] addBit: [self pieceForPlayer: 1-player]];
   8.119 +    }
   8.120  }
   8.121  
   8.122  
   8.123  - (BOOL) applyMoveString: (NSString*)move
   8.124  {
   8.125 -    NSLog(@"Go: applyMoveString: '%@'",move);
   8.126 +    //NSLog(@"Go: applyMoveString: '%@'",move);
   8.127      return [self animatePlacementIn: [_board cellWithName: move]];
   8.128  }
   8.129  
     9.1 --- a/Source/QuartzUtils.m	Fri Jul 18 13:26:59 2008 -0700
     9.2 +++ b/Source/QuartzUtils.m	Mon Jul 21 17:32:21 2008 -0700
     9.3 @@ -69,7 +69,7 @@
     9.4  {
     9.5  #if TARGET_OS_IPHONE
     9.6      UIImage *uiImage = [UIImage imageWithContentsOfFile: path];
     9.7 -    if(!uiImage) NSLog(@"Warning: UIImage imageWithContentsOfFile failed on file %@",path);
     9.8 +    if(!uiImage) Warn(@"UIImage imageWithContentsOfFile failed on file %@",path);
     9.9      return CGImageRetain(uiImage.CGImage);
    9.10  #else
    9.11      CGImageRef image = NULL;
    9.12 @@ -78,7 +78,7 @@
    9.13      if( src ) {
    9.14          image = CGImageSourceCreateImageAtIndex(src, 0, NULL);
    9.15          CFRelease(src);
    9.16 -        if(!image) NSLog(@"Warning: CGImageSourceCreateImageAtIndex failed on file %@ (ptr size=%u)",path,sizeof(void*));
    9.17 +        if(!image) Warn(@"CGImageSourceCreateImageAtIndex failed on file %@ (ptr size=%u)",path,sizeof(void*));
    9.18      }
    9.19      return image;
    9.20  #endif
    10.1 --- a/Source/Stack.h	Fri Jul 18 13:26:59 2008 -0700
    10.2 +++ b/Source/Stack.h	Mon Jul 21 17:32:21 2008 -0700
    10.3 @@ -47,11 +47,14 @@
    10.4  @property int wrapInterval;                 // How many Bits to add before wrapping
    10.5  @property BOOL dragAsStacks;                // If set to YES, dragging a Bit drags a DraggedStack
    10.6  @property (readonly) NSArray *bits;         // The Bits, in order
    10.7 +@property NSUInteger numberOfBits;          // Number of bits (can be used to remove bits, but not add)
    10.8  @property (readonly) Bit *topBit;           // The topmost Bit (last item in self.bits)
    10.9  
   10.10  /** Adds a Bit to the end */
   10.11  - (void) addBit: (Bit*)bit;
   10.12  
   10.13 +- (void) removeBit: (Bit*)bit;
   10.14 +
   10.15  @end
   10.16  
   10.17  
    11.1 --- a/Source/Stack.m	Fri Jul 18 13:26:59 2008 -0700
    11.2 +++ b/Source/Stack.m	Mon Jul 21 17:32:21 2008 -0700
    11.3 @@ -63,6 +63,18 @@
    11.4  @synthesize bits=_bits;
    11.5  
    11.6  
    11.7 +- (NSUInteger) numberOfBits
    11.8 +{
    11.9 +    return _bits.count;
   11.10 +}
   11.11 +
   11.12 +- (void) setNumberOfBits: (NSUInteger)n
   11.13 +{
   11.14 +    NSAssert2(n<=_bits.count,@"Cannot increase numberOfBits (from %u to %u)", _bits.count,n);
   11.15 +    while( _bits.count > n )
   11.16 +        [self removeBit: self.topBit];
   11.17 +}
   11.18 +
   11.19  - (Bit*) topBit
   11.20  {
   11.21      return [_bits lastObject];
   11.22 @@ -98,6 +110,16 @@
   11.23  }
   11.24  
   11.25  
   11.26 +- (void) removeBit: (Bit*)bit
   11.27 +{
   11.28 +    NSUInteger index = [_bits indexOfObjectIdenticalTo: bit];
   11.29 +    if( index != NSNotFound ) {
   11.30 +        [bit removeFromSuperlayer];
   11.31 +        [_bits removeObjectAtIndex: index];
   11.32 +    }
   11.33 +}
   11.34 +
   11.35 +
   11.36  - (void) setHighlighted: (BOOL)highlighted
   11.37  {
   11.38      [super setHighlighted: highlighted];