* 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.
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];