Source/Grid.m
changeset 14 4585c74d809c
parent 11 436cbdf56810
child 15 73f8c889f053
     1.1 --- a/Source/Grid.m	Sat Jul 05 17:46:43 2008 -0700
     1.2 +++ b/Source/Grid.m	Tue Jul 08 20:32:52 2008 -0700
     1.3 @@ -22,7 +22,8 @@
     1.4  */
     1.5  #import "Grid.h"
     1.6  #import "Bit.h"
     1.7 -#import "Game.h"
     1.8 +#import "Piece.h"
     1.9 +#import "Game+Protected.h"
    1.10  #import "Player.h"
    1.11  #import "QuartzUtils.h"
    1.12  
    1.13 @@ -112,8 +113,7 @@
    1.14  }
    1.15  
    1.16  @synthesize cellClass=_cellClass, rows=_nRows, columns=_nColumns, spacing=_spacing,
    1.17 -            usesDiagonals=_usesDiagonals, allowsMoves=_allowsMoves, allowsCaptures=_allowsCaptures,
    1.18 -            cells=_cells;
    1.19 +            usesDiagonals=_usesDiagonals, allowsMoves=_allowsMoves, allowsCaptures=_allowsCaptures;
    1.20  
    1.21  
    1.22  #pragma mark -
    1.23 @@ -184,6 +184,16 @@
    1.24  }
    1.25  
    1.26  
    1.27 +- (NSArray*) cells
    1.28 +{
    1.29 +    NSMutableArray *cells = [_cells mutableCopy];
    1.30 +    for( int i=cells.count-1; i>=0; i-- )
    1.31 +        if( [cells objectAtIndex: i] == [NSNull null] )
    1.32 +            [cells removeObjectAtIndex: i];
    1.33 +    return cells;
    1.34 +}
    1.35 +
    1.36 +
    1.37  - (GridCell*) cellWithName: (NSString*)name
    1.38  {
    1.39      for( CALayer *layer in self.sublayers )
    1.40 @@ -194,6 +204,61 @@
    1.41  }
    1.42  
    1.43  
    1.44 +- (NSCountedSet*) countPiecesByPlayer
    1.45 +{
    1.46 +    NSCountedSet *players = [NSCountedSet set];
    1.47 +    for( GridCell *cell in self.cells ) {
    1.48 +        Player *owner = cell.bit.owner;
    1.49 +        if( owner )
    1.50 +            [players addObject: owner];
    1.51 +    }
    1.52 +    return players;
    1.53 +}
    1.54 +
    1.55 +
    1.56 +
    1.57 +#pragma mark -
    1.58 +#pragma mark GAME STATE:
    1.59 +
    1.60 +
    1.61 +- (NSString*) stateString
    1.62 +{
    1.63 +    NSMutableString *state = [NSMutableString stringWithCapacity: _cells.count];
    1.64 +    for( GridCell *cell in self.cells ) {
    1.65 +        Bit *bit = cell.bit;
    1.66 +        NSString *name = bit ?bit.name :@"-";
    1.67 +        NSAssert(name.length==1,@"Missing or multicharacter name");
    1.68 +        [state appendString: name];
    1.69 +    }
    1.70 +    return state;
    1.71 +}
    1.72 +
    1.73 +- (void) setStateString: (NSString*)state
    1.74 +{
    1.75 +    Game *game = self.game;
    1.76 +    int i = 0;
    1.77 +    for( GridCell *cell in self.cells )
    1.78 +        cell.bit = [game makePieceNamed: [state substringWithRange: NSMakeRange(i++,1)]];
    1.79 +}
    1.80 +
    1.81 +
    1.82 +- (BOOL) applyMoveString: (NSString*)move
    1.83 +{
    1.84 +    GridCell *src = nil;
    1.85 +    for( NSString *ident in [move componentsSeparatedByString: @"-"] ) {
    1.86 +        while( [ident hasSuffix: @"!"] || [ident hasSuffix: @"*"] )
    1.87 +            ident = [ident substringToIndex: ident.length-1];
    1.88 +        GridCell *dst = [self cellWithName: ident];
    1.89 +        if( dst == nil )
    1.90 +            return NO;
    1.91 +        if( src && ! [self.game animateMoveFrom: src to: dst] )
    1.92 +            return NO;
    1.93 +        src = dst;
    1.94 +    }
    1.95 +    return YES;
    1.96 +}
    1.97 +
    1.98 +
    1.99  #pragma mark -
   1.100  #pragma mark DRAWING:
   1.101  
   1.102 @@ -464,6 +529,41 @@
   1.103  - (Square*) l      {return self.fwdIsN ?self.w  :self.e;}
   1.104  
   1.105  
   1.106 +static int sgn( int n ) {return n<0 ?-1 :(n>0 ?1 :0);}
   1.107 +
   1.108 +
   1.109 +- (SEL) directionToCell: (GridCell*)dst
   1.110 +{
   1.111 +    static NSString* const kDirections[9] = {@"sw", @"s", @"se",
   1.112 +                                             @"w",  nil,  @"e",
   1.113 +                                             @"nw", @"n", @"ne"};
   1.114 +    if( dst.grid != self.grid )
   1.115 +        return NULL;
   1.116 +    int dy=dst.row-_row, dx=dst.column-_column;
   1.117 +    if( dx && dy )
   1.118 +        if( !( _grid.usesDiagonals && abs(dx)==abs(dy) ) )
   1.119 +            return NULL;
   1.120 +    NSString *dir = kDirections[ 3*(sgn(dy)+1) + (sgn(dx)+1) ];
   1.121 +    return dir ?NSSelectorFromString(dir) :NULL;
   1.122 +}
   1.123 +
   1.124 +- (NSArray*) lineToCell: (GridCell*)dst inclusive: (BOOL)inclusive;
   1.125 +{
   1.126 +    SEL dir = [self directionToCell: dst];
   1.127 +    if( ! dir )
   1.128 +        return nil;
   1.129 +    NSMutableArray *line = [NSMutableArray array];
   1.130 +    GridCell *cell;
   1.131 +    for( cell=self; cell; cell = [cell performSelector: dir] ) {
   1.132 +        if( inclusive || (cell!=self && cell!=dst) )
   1.133 +            [line addObject: cell];
   1.134 +        if( cell==dst )
   1.135 +            return line;
   1.136 +    }
   1.137 +    return nil; // should be impossible, but just in case
   1.138 +}
   1.139 +                
   1.140 +
   1.141  #if ! TARGET_OS_IPHONE
   1.142  
   1.143  - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender