jens@10: // jens@10: // Turn.m jens@10: // YourMove jens@10: // jens@10: // Created by Jens Alfke on 7/3/08. jens@10: // Copyright 2008 Jens Alfke. All rights reserved. jens@10: // jens@10: jens@10: #import "Turn.h" jens@10: #import "Game+Protected.h" jens@10: #import "Player.h" jens@10: jens@10: jens@10: NSString* const kTurnCompleteNotification = @"TurnComplete"; jens@10: jens@10: jens@10: @interface Turn () jens@10: @property (copy) NSString *move, *boardState; jens@10: @property (retain) NSDate *date; jens@10: @end jens@10: jens@10: jens@10: jens@10: @implementation Turn jens@10: jens@10: jens@10: - (id) initWithPlayer: (Player*)player jens@10: { jens@10: NSParameterAssert(player!=nil); jens@10: self = [super init]; jens@10: if (self != nil) { jens@10: _game = player.game; jens@10: _player = player; jens@10: _status = kTurnEmpty; jens@10: self.boardState = _game.latestTurn.boardState; jens@10: } jens@10: return self; jens@10: } jens@10: jens@10: - (id) initStartOfGame: (Game*)game jens@10: { jens@10: NSParameterAssert(game!=nil); jens@10: self = [super init]; jens@10: if (self != nil) { jens@10: _game = game; jens@10: _status = kTurnFinished; jens@10: self.boardState = game.initialStateString; jens@10: self.date = [NSDate date]; jens@10: } jens@10: return self; jens@10: } jens@10: jens@10: jens@10: - (id) initWithCoder: (NSCoder*)decoder jens@10: { jens@10: self = [self init]; jens@10: if( self ) { jens@10: _game = [decoder decodeObjectForKey: @"game"]; jens@10: _player = [decoder decodeObjectForKey: @"player"]; jens@10: _status = [decoder decodeIntForKey: @"status"]; jens@10: _move = [[decoder decodeObjectForKey: @"move"] copy]; jens@10: _boardState = [[decoder decodeObjectForKey: @"boardState"] copy]; jens@10: _date = [[decoder decodeObjectForKey: @"date"] copy]; jens@10: _comment = [[decoder decodeObjectForKey: @"comment"] copy]; jens@10: } jens@10: return self; jens@10: } jens@10: jens@10: - (void) encodeWithCoder: (NSCoder*)coder jens@10: { jens@10: [coder encodeObject: _game forKey: @"game"]; jens@10: [coder encodeObject: _player forKey: @"player"]; jens@10: [coder encodeInt: _status forKey: @"status"]; jens@10: [coder encodeObject: _move forKey: @"move"]; jens@10: [coder encodeObject: _boardState forKey: @"boardState"]; jens@10: [coder encodeObject: _date forKey: @"date"]; jens@10: [coder encodeObject: _comment forKey: @"comment"]; jens@10: } jens@10: jens@10: - (void) dealloc jens@10: { jens@10: [_move release]; jens@10: [_boardState release]; jens@10: [_date release]; jens@10: [_comment release]; jens@10: [super dealloc]; jens@10: } jens@10: jens@10: jens@10: - (NSString*) description jens@10: { jens@10: return [NSString stringWithFormat: @"%@[%@, #%i, %@]", self.class, _game.class, self.turnNumber, _move]; jens@10: } jens@10: jens@10: jens@10: @synthesize game=_game, player=_player, move=_move, boardState=_boardState, date=_date, comment=_comment, jens@10: replaying=_replaying; jens@10: jens@10: jens@10: - (unsigned) turnNumber {return [_game.turns indexOfObjectIdenticalTo: self];} jens@10: - (BOOL) isLatestTurn {return _game.turns.lastObject == self;} jens@10: - (Player*) nextPlayer {return _player ?_player.nextPlayer :[_game.players objectAtIndex: 0];} jens@10: - (TurnStatus) status {return _status;} jens@10: jens@10: - (void) setStatus: (TurnStatus)status jens@10: { jens@10: BOOL ok = NO; jens@10: switch( _status ) { jens@10: case kTurnEmpty: jens@10: ok = (status==kTurnPartial) || (status==kTurnComplete); jens@10: break; jens@10: case kTurnPartial: jens@10: ok = (status==kTurnEmpty) || (status==kTurnComplete) || (status==kTurnFinished); jens@10: break; jens@10: case kTurnComplete: jens@10: ok = (status==kTurnEmpty) || (status==kTurnPartial) || (status==kTurnFinished); jens@10: break; jens@10: case kTurnFinished: jens@10: break; jens@10: } jens@10: NSAssert2(ok,@"Illegal Turn status transition %i -> %i", _status,status); jens@10: jens@10: [self captureBoardState]; jens@10: _status = status; jens@10: if( _status==kTurnEmpty ) { jens@10: self.move = nil; jens@10: self.date = nil; jens@10: } else jens@10: self.date = [NSDate date]; jens@10: } jens@10: jens@10: jens@16: - (void) _unfinish jens@16: { jens@16: NSAssert(_status==kTurnFinished,@"Turn must be finished"); jens@16: [self willChangeValueForKey: @"status"]; jens@16: _status = kTurnComplete; jens@16: [self didChangeValueForKey: @"status"]; jens@16: } jens@16: jens@16: jens@15: - (Turn*) previousTurn jens@15: { jens@15: unsigned n = self.turnNumber; jens@15: if( n > 0 ) jens@15: return [_game.turns objectAtIndex: n-1]; jens@15: else jens@15: return nil; jens@15: } jens@15: jens@15: - (Turn*) nextTurn jens@15: { jens@15: unsigned n = self.turnNumber; jens@15: if( n+1 < _game.turns.count ) jens@15: return [_game.turns objectAtIndex: n+1]; jens@15: else jens@15: return nil; jens@15: } jens@15: jens@15: jens@10: - (void) addToMove: (NSString*)move jens@10: { jens@10: if( ! _replaying ) { jens@10: NSParameterAssert(move.length); jens@10: NSAssert(_status