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
|
//
// SabotageGame.m
// Gridlock
//
// Created by Brian on 3/27/05.
// Copyright 2005 __MyCompanyName__. All rights reserved.
//
#import "SabotageGame.h"
@implementation SabotageGame
-(void)reset {
[super reset];
[self createGridFromConfiguration];
}
-(DCHypergridPosition *)goalPositionForPlayer:(int)pnum {
NSString *key = (pnum==1) ? @"p1Goal" : @"p2Goal";
NSArray *coords = [[self configurationInfo] objectForKey:key];
return [DCHypergridPosition positionWithRow:[[coords objectAtIndex:0] intValue] column:[[coords objectAtIndex:1] intValue]];
}
-(int)playerWithGoalPosition:(DCHypergridPosition *)pos {
int i;
for(i=1; i<=[self numberOfPlayers]; i++) {
if ([pos isEqual:[self goalPositionForPlayer:i]]) return i;
}
return 0;
}
-(int)rangeForPieceAtPosition:(DCHypergridPosition *)pos {
int range=0;
int c = [pos column];
int r;
for(r=0; r<[self numberOfRows]; r++) {
int value = [self valueAtRow:r column:c];
if (value==1 || value==2 || value==-1 || value==-2) ++range;
}
return range;
}
-(void)appendValidMovesFromPosition:(DCHypergridPosition *)pos forPlayer:(int)pnum intoArray:(NSMutableArray *)moves {
int range = [self rangeForPieceAtPosition:pos];
int r = [pos row];
int c = [pos column];
int dr,dc;
for(dr=-1; dr<=+1; dr++) {
for(dc=-1; dc<=+1; dc++) {
if (dr!=0 || dc!=0) {
// destination must be empty, enemy, or neutral king
if ([self isValidRow:r+range*dr column:c+range*dc]) {
if (abs([self valueAtRow:r+range*dr column:c+range*dc])!=pnum) {
// destination is valid, path must be clear
BOOL good = YES;
int d;
for(d=1; d<range && good; d++) {
if ([self valueAtRow:r+d*dr column:c+d*dc]!=0) good = NO;
}
if (good) {
[moves addObject:[NSArray arrayWithObjects:pos, [DCHypergridPosition positionWithRow:r+range*dr column:c+range*dc], nil]];
}
}
}
}
}
}
}
-(NSArray *)allValidMoveSequences {
int pnum = [self currentPlayerNumber];
NSMutableArray *moves = [NSMutableArray array];
NSEnumerator *pe = [[self grid] enumeratorForPositionsWithValue:pnum];
id pos;
while((pos=[pe nextObject])) {
[self appendValidMovesFromPosition:pos forPlayer:pnum intoArray:moves];
}
// check for king
pos = [[self grid] positionWithValue:-pnum];
if (pos) {
[self appendValidMovesFromPosition:pos forPlayer:pnum intoArray:moves];
}
return moves;
}
-(BOOL)prepareMoveSequence:(NSArray *)positions {
if ([positions count]!=2) return NO;
id startpos = [positions objectAtIndex:0];
id endpos = [positions objectAtIndex:1];
int pnum = [self currentPlayerNumber];
[self resetFutureGrid];
[[self futureGrid] setValue:0 atPosition:startpos];
BOOL isKing = ([self valueAtPosition:startpos]<0 || [self valueAtPosition:endpos]<0);
[[self futureGrid] setValue:(isKing ? -pnum : pnum) atPosition:endpos];
return YES;
}
-(BOOL)isGameOver {
return ([self winningPlayer]!=0);
}
-(int)winningPlayer {
// check for carrier reaching goal
if ([self valueAtPosition:[self goalPositionForPlayer:1]]==-1) return 1;
if ([self valueAtPosition:[self goalPositionForPlayer:2]]==-2) return 2;
// check for all pieces eliminated
if (![[self grid] hasCellWithValue:1] && ![[self grid] hasCellWithValue:-1]) return 2;
if (![[self grid] hasCellWithValue:2] && ![[self grid] hasCellWithValue:-2]) return 1;
return 0;
}
@end
|