// // DiagonalsGame.m // Gridlock // // Created by Brian on Sat Jul 10 2004. // Copyright (c) 2004 __MyCompanyName__. All rights reserved. // #import "DiagonalsGame.h" @implementation DiagonalsGame idAccessor(preparedMove, setPreparedMove) -(void)reset { [super reset]; [self setGrid:[DCHypergrid gridWithRows:[[[self configurationInfo] objectForKey:@"rows"] intValue] columns:[[[self configurationInfo] objectForKey:@"cols"] intValue]]]; p1Score = p2Score = 0; [self setPreparedMove:nil]; } -(BOOL)prepareMoveSequence:(NSArray *)positions { [self setPreparedMove:[positions lastObject]]; return YES; } -(NSArray *)positionsOfAllChangingCells { return [[self preparedMove] arrayWithSelf_]; } -(int)futureValueAtPosition:(DCHypergridPosition *)pos { if ([pos isEqual:[self preparedMove]]) return [self currentPlayerNumber]; else return [self valueAtPosition:pos]; } -(int)scoreForDiagonalFromPosition:(id)pos northEast:(BOOL)ne { int score = 1; // count position moved to BOOL longerThan1 = NO; // corners don't count int pnum = [self valueAtPosition:pos]; // go forward diagonally until we hit the edge or an empty cell int r = [pos row]; int c = [pos column]; int dc = ne ? 1 : -1; while ([self isValidRow:r+1 column:c+dc]) { int val = [self valueAtRow:r+1 column:c+dc]; if (val==0) return 0; // not a full diagonal if (val==pnum) score++; longerThan1 = YES; r++; c+=dc; } // repeat in opposite direction r = [pos row]; c = [pos column]; while ([self isValidRow:r-1 column:c-dc]) { int val = [self valueAtRow:r-1 column:c-dc]; if (val==0) return 0; // not a full diagonal if (val==pnum) score++; longerThan1 = YES; r--; c-=dc; } return (longerThan1) ? score : 0; } -(int)scoreForDiagonalsFromPosition:(id)pos { return [self scoreForDiagonalFromPosition:pos northEast:YES] + [self scoreForDiagonalFromPosition:pos northEast:NO]; } -(void)updateFromPreparedMove { id pos = [self preparedMove]; [super updateFromPreparedMove]; // check for completed diagonals int score = [self scoreForDiagonalsFromPosition:pos]; if ([self currentPlayerNumber]==1) { p1Score += score; } else { p2Score += score; } } -(NSArray *)allValidMoveSequences { return [[[self grid] allPositionsWithValue:0] valuesByObjectsPerformingSelector:@selector(arrayWithSelf_)]; } -(BOOL)showScores { return YES; } -(int)scoreForPlayer:(int)pnum { return (pnum==1) ? p1Score : p2Score; } -(BOOL)isGameOver { return !([[self grid] hasCellWithValue:0]); } // these methods deal with the score ivars (since they can't be derived from the state of the board) -(Game *)copy { DiagonalsGame *newGame = (DiagonalsGame *)[super copy]; newGame->p1Score = p1Score; newGame->p2Score = p2Score; return newGame; } -(void)copyValuesToGame:(DiagonalsGame *)newGame { [super copyValuesToGame:newGame]; newGame->p1Score = p1Score; newGame->p2Score = p2Score; } -(id)propertyList { id plist = [super propertyList]; // assume mutable? [plist setObject:[[NSNumber numberWithInt:p1Score] stringValue] forKey:@"p1Score"]; [plist setObject:[[NSNumber numberWithInt:p2Score] stringValue] forKey:@"p2Score"]; return plist; } -(void)updateFromPropertyList:(id)plist { [super updateFromPropertyList:plist]; p1Score = [[plist objectForKey:@"p1Score"] intValue]; p2Score = [[plist objectForKey:@"p2Score"] intValue]; } @end