1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
//
// 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
|