File: DiagonalsGame.m

package info (click to toggle)
gridlock.app 1.10-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,556 kB
  • sloc: objc: 10,334; ansic: 669; makefile: 12
file content (131 lines) | stat: -rw-r--r-- 3,505 bytes parent folder | download
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
//
//  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:(DCHypergridPosition *)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