//
//  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
