// // DaggerGame.m // Gridlock // // Created by Brian on Sun Feb 29 2004. // Copyright (c) 2004 __MyCompanyName__. All rights reserved. // #import "DaggerGame.h" @implementation DaggerGame -(void)reset { [super reset]; [self createGridFromConfiguration]; } -(int)ownerOfPosition:(DCHypergridPosition *)pos { return abs([self valueAtPosition:pos]); } -(int)ownerOfRow:(int)r column:(int)c { return abs([self valueAtRow:r column:c]); } -(BOOL)isCrownAtPosition:(DCHypergridPosition *)pos { return ([self valueAtPosition:pos]<0); } -(BOOL)isCrownAtRow:(int)r column:(int)c { return ([self valueAtRow:r column:c]<0); } -(int)numberOfDaggersForPlayer:(int)pnum { return [[self grid] numberOfCellsWithValue:pnum]; } -(int)numberOfCrownsForPlayer:(int)pnum{ return [[self grid] numberOfCellsWithValue:-pnum]; } -(BOOL)prepareMoveSequence:(NSArray *)positions { [self resetFutureGrid]; [[self futureGrid] setValue:0 atPosition:[positions objectAtIndex:0]]; [[self futureGrid] setValue:[self valueAtPosition:[positions objectAtIndex:0]] atPosition:[positions objectAtIndex:1]]; return YES; } -(int)winningPlayer { return [self nextPlayerNumber]; } -(void)appendValidDaggerMovesFromPosition:(id)pos forPlayer:(int)pnum intoArray:(NSMutableArray *)moves { int r = [pos row]; int c = [pos column]; // check diagonally uphill if ([self isValidRow:r+1 column:c-1] && [self ownerOfRow:r+1 column:c-1]!=pnum) { [moves addObject:[NSArray arrayWithObjects:pos, [DCHypergridPosition positionWithRow:r+1 column:c-1], nil]]; } if ([self isValidRow:r+1 column:c+1] && [self ownerOfRow:r+1 column:c+1]!=pnum) { [moves addObject:[NSArray arrayWithObjects:pos, [DCHypergridPosition positionWithRow:r+1 column:c+1], nil]]; } // check directly uphill, can't capture daggers if ([self isValidRow:r+1 column:c]) { int owner = [self ownerOfRow:r+1 column:c]; if (owner==0 || (owner!=pnum && [self isCrownAtRow:r+1 column:c])) { [moves addObject:[NSArray arrayWithObjects:pos, [DCHypergridPosition positionWithRow:r+1 column:c], nil]]; } } // check downhill int dc; int i; for(dc=-1; dc<=+1; dc++) { BOOL done = NO; for(i=1; !done; i++) { int endr = r-i; int endc = c+i*dc; if ([self isValidRow:endr column:endc]) { int owner = [self ownerOfRow:endr column:endc]; if (owner==0) { [moves addObject:[NSArray arrayWithObjects:pos, [DCHypergridPosition positionWithRow:endr column:endc], nil]]; } else { // we hit another piece, capture if we can if (owner!=pnum && (dc!=0 || [self isCrownAtRow:endr column:endc])) { [moves addObject:[NSArray arrayWithObjects:pos, [DCHypergridPosition positionWithRow:endr column:endc], nil]]; } done = YES; } } else done = YES; } } } -(void)appendValidCrownMovesFromPosition:(id)pos forPlayer:(int)pnum intoArray:(NSMutableArray *)moves { NSEnumerator *pe = [[[self grid] neighborsOfPosition:pos distance:1] objectEnumerator]; id npos; while (npos=[pe nextObject]) { if ([self ownerOfPosition:npos]!=pnum) { [moves addObject:[NSArray arrayWithObjects:pos,npos,nil]]; } } } -(NSArray *)allValidMoveSequences { int pnum = [self currentPlayerNumber]; NSMutableArray *moves = [NSMutableArray array]; NSEnumerator *posEnum = [[self grid] positionEnumerator]; id position; while (position=[posEnum nextObject]) { int value = [self valueAtPosition:position]; if (value==pnum) { [self appendValidDaggerMovesFromPosition:position forPlayer:pnum intoArray:moves]; } else if (value==-pnum) { [self appendValidCrownMovesFromPosition:position forPlayer:pnum intoArray:moves]; } } if ([moves count]==0) [moves addObject:[NSArray array]]; return moves; } -(int)playerWithCrownAtLastRow { int c; int maxr = [self numberOfRows]-1; for(c=[self numberOfColumns]-1; c>=0; c--) { if ([self valueAtRow:0 column:c]==-2) return 2; if ([self valueAtRow:maxr column:c]==-1) return 1; } return 0; } -(BOOL)isGameOver { return [self numberOfCrownsForPlayer:1]<2 || [self numberOfCrownsForPlayer:2]<2 || [self playerWithCrownAtLastRow]>0; } @end