Source/Turn.m
author Jens Alfke <jens@mooseyard.com>
Thu Jul 17 13:29:04 2008 -0700 (2008-07-17)
changeset 19 3b750982ff39
parent 15 73f8c889f053
permissions -rw-r--r--
Don't load Checkers sound files till a game is displayed on a board; this speeds up launch.
     1 //
     2 //  Turn.m
     3 //  YourMove
     4 //
     5 //  Created by Jens Alfke on 7/3/08.
     6 //  Copyright 2008 Jens Alfke. All rights reserved.
     7 //
     8 
     9 #import "Turn.h"
    10 #import "Game+Protected.h"
    11 #import "Player.h"
    12 
    13 
    14 NSString* const kTurnCompleteNotification = @"TurnComplete";
    15 
    16 
    17 @interface Turn ()
    18 @property (copy) NSString *move, *boardState;
    19 @property (retain) NSDate *date;
    20 @end
    21 
    22 
    23 
    24 @implementation Turn
    25 
    26 
    27 - (id) initWithPlayer: (Player*)player
    28 {
    29     NSParameterAssert(player!=nil);
    30     self = [super init];
    31     if (self != nil) {
    32         _game = player.game;
    33         _player = player;
    34         _status = kTurnEmpty;
    35         self.boardState = _game.latestTurn.boardState;
    36     }
    37     return self;
    38 }
    39 
    40 - (id) initStartOfGame: (Game*)game
    41 {
    42     NSParameterAssert(game!=nil);
    43     self = [super init];
    44     if (self != nil) {
    45         _game = game;
    46         _status = kTurnFinished;
    47         self.boardState = game.initialStateString;
    48         self.date = [NSDate date];
    49     }
    50     return self;
    51 }
    52 
    53 
    54 - (id) initWithCoder: (NSCoder*)decoder
    55 {
    56     self = [self init];
    57     if( self ) {
    58         _game =        [decoder decodeObjectForKey: @"game"];
    59         _player =      [decoder decodeObjectForKey: @"player"];
    60         _status =      [decoder decodeIntForKey: @"status"];
    61         _move =       [[decoder decodeObjectForKey: @"move"] copy];
    62         _boardState = [[decoder decodeObjectForKey: @"boardState"] copy];
    63         _date =       [[decoder decodeObjectForKey: @"date"] copy];
    64         _comment =    [[decoder decodeObjectForKey: @"comment"] copy];
    65     }
    66     return self;
    67 }
    68 
    69 - (void) encodeWithCoder: (NSCoder*)coder
    70 {
    71     [coder encodeObject: _game       forKey: @"game"];
    72     [coder encodeObject: _player     forKey: @"player"];
    73     [coder encodeInt:    _status     forKey: @"status"];
    74     [coder encodeObject: _move       forKey: @"move"];
    75     [coder encodeObject: _boardState forKey: @"boardState"];
    76     [coder encodeObject: _date       forKey: @"date"];
    77     [coder encodeObject: _comment    forKey: @"comment"];
    78 }
    79 
    80 - (void) dealloc
    81 {
    82     [_move release];
    83     [_boardState release];
    84     [_date release];
    85     [_comment release];
    86     [super dealloc];
    87 }
    88 
    89 
    90 - (NSString*) description
    91 {
    92     return [NSString stringWithFormat: @"%@[%@, #%i, %@]", self.class, _game.class, self.turnNumber, _move];
    93 }
    94 
    95 
    96 @synthesize game=_game, player=_player, move=_move, boardState=_boardState, date=_date, comment=_comment,
    97             replaying=_replaying;
    98 
    99 
   100 - (unsigned) turnNumber     {return [_game.turns indexOfObjectIdenticalTo: self];}
   101 - (BOOL) isLatestTurn       {return _game.turns.lastObject == self;}
   102 - (Player*) nextPlayer      {return _player ?_player.nextPlayer :[_game.players objectAtIndex: 0];}
   103 - (TurnStatus) status       {return _status;}
   104 
   105 - (void) setStatus: (TurnStatus)status
   106 {
   107     BOOL ok = NO;
   108     switch( _status ) {
   109         case kTurnEmpty:
   110             ok = (status==kTurnPartial) || (status==kTurnComplete);
   111             break;
   112         case kTurnPartial:
   113             ok = (status==kTurnEmpty) || (status==kTurnComplete) || (status==kTurnFinished);
   114             break;
   115         case kTurnComplete:
   116             ok = (status==kTurnEmpty) || (status==kTurnPartial) || (status==kTurnFinished);
   117             break;
   118         case kTurnFinished:
   119             break;
   120     }
   121     NSAssert2(ok,@"Illegal Turn status transition %i -> %i", _status,status);
   122     
   123     [self captureBoardState];
   124     _status = status;
   125     if( _status==kTurnEmpty ) {
   126         self.move = nil;
   127         self.date = nil;
   128     } else
   129         self.date = [NSDate date];
   130 }
   131 
   132 
   133 - (void) _unfinish
   134 {
   135     NSAssert(_status==kTurnFinished,@"Turn must be finished");
   136     [self willChangeValueForKey: @"status"];
   137     _status = kTurnComplete;
   138     [self didChangeValueForKey: @"status"];
   139 }
   140 
   141 
   142 - (Turn*) previousTurn
   143 {
   144     unsigned n = self.turnNumber;
   145     if( n > 0 )
   146         return [_game.turns objectAtIndex: n-1];
   147     else
   148         return nil;
   149 }
   150 
   151 - (Turn*) nextTurn
   152 {
   153     unsigned n = self.turnNumber;
   154     if( n+1 < _game.turns.count )
   155         return [_game.turns objectAtIndex: n+1];
   156     else
   157         return nil;
   158 }
   159 
   160 
   161 - (void) addToMove: (NSString*)move
   162 {
   163     if( ! _replaying ) {
   164         NSParameterAssert(move.length);
   165         NSAssert(_status<kTurnComplete,@"Complete Turn can't be modified");
   166         if( _move )
   167             move = [_move stringByAppendingString: move];
   168         self.move = move;
   169         [self captureBoardState];
   170         self.date = [NSDate date];
   171         if( _status==kTurnEmpty )
   172             self.status = kTurnPartial;
   173     }
   174 }
   175 
   176 
   177 - (void) captureBoardState
   178 {
   179     if( ! _replaying ) {
   180         NSAssert(_status<kTurnFinished,@"Finished Turn can't be modified");
   181         if( _game.table )
   182             self.boardState = _game.stateString;
   183     }
   184 }
   185 
   186 
   187 @end