📄 board.m
字号:
{ if (BOARD(i, j) COMPARE_TILE (human | computer)) { tmp_calculate[INDEX (i+1, j-1)]++; tmp_calculate[INDEX (i+1, j )]++; tmp_calculate[INDEX (i+1, j+1)]++; tmp_calculate[INDEX (i, j-1)]++; tmp_calculate[INDEX (i, j+1)]++; tmp_calculate[INDEX (i-1, j-1)]++; tmp_calculate[INDEX (i-1, j )]++; tmp_calculate[INDEX (i-1, j+1)]++; } } } /* avoid squares already occupied */ for (i = 0; i < size; i++) { for(j = 0; j < size; j++) { if (BOARD(i, j) COMPARE_TILE (human | computer)) { tmp_calculate[INDEX (i, j)]=0; } else { /* we store here a non-busy cell in case we don't find anything better */ i_max=i; j_max=j; } } } /* now we extract the solution */ for (i = 0; i < size; i++) { for(j = 0; j < size; j++) { if (difficultyLevel >= 3) { if (tmp_calculate[INDEX (i, j)] >= max) { tmp_importance = [self powerOfSquareInRow: i column: j]; if ((tmp_calculate[INDEX (i, j)] > max) || (tmp_importance > importance_of_max)) { importance_of_max = tmp_importance; max = tmp_calculate[INDEX (i, j)]; i_max=i; j_max=j; } } } else { /* same without being too smart - just look for the most crowded board square */ if (tmp_calculate[INDEX (i, j)] > max) { max = tmp_calculate[INDEX (i, j)]; i_max = i; j_max = j; } } } } BOARD(i_max, j_max) = computer; last_move_row = i_max; last_move_col = j_max; free (tmp_calculate); return YES;}- (BOOL) computerOrHumanWinNext { patternPosition pos; int index; for (index = 0; index < 5; index++) { pos = [self scanBoardForPattern: computerWonNextPattern[index] length: 5]; if (PATTERN_FOUND (pos)) { int a, i, j; i = pos.startRow; j = pos.startColumn; for (a = 0; a < index; a++) { i += pos.directionRow; j += pos.directionColumn; } BOARD(i, j) = computer; last_move_row = i; last_move_col = j; return YES; } } for (index = 0; index < 5; index++) { pos = [self scanBoardForPattern: humanWonNextPattern[index] length: 5]; if (PATTERN_FOUND (pos)) { int a, i, j; i = pos.startRow; j = pos.startColumn; for (a = 0; a < index; a++) { i += pos.directionRow; j += pos.directionColumn; } BOARD(i, j) = computer; last_move_row = i; last_move_col = j; return YES; } } return NO;}- (BOOL) computerOrHumanWinFar{ patternPosition pos; int index; for (index = 0; index < 4; index++) { pos = [self scanBoardForPattern: computerWonFarPattern[index] length: 6]; if (PATTERN_FOUND (pos)) { int a, i, j; i = pos.startRow; j = pos.startColumn; for (a = 0; a < (index + 1); a++) { i += pos.directionRow; j += pos.directionColumn; } BOARD(i, j) = computer; last_move_row = i; last_move_col = j; return YES; } } for (index = 0; index < 4; index++) { pos = [self scanBoardForPattern: humanWonFarPattern[index] length: 6]; if (PATTERN_FOUND (pos)) { int a, i, j; i = pos.startRow; j = pos.startColumn; for (a = 0; a < (index + 1); a++) { i += pos.directionRow; j += pos.directionColumn; } BOARD(i, j) = computer; last_move_row = i; last_move_col = j; return YES; } } return NO;}- (void) performComputerMove{ switch (difficultyLevel) { case 5: case 4: case 3: if ([self computerOrHumanWinNext] == YES) { break; } if ([self computerOrHumanWinFar] == YES) { break; } /* All the refinement for higher levels goes here */ [self computerMoveInCrowdedPlace]; break; case 2: if ([self computerOrHumanWinNext] == YES) { break; } if ([self computerOrHumanWinFar] == YES) { break; } [self computerMoveInCrowdedPlace]; break; case 1: if ([self computerOrHumanWinNext] == YES) { break; } /* else fall back on level 0 strategy */ case 0: default: [self computerMoveInCrowdedPlace]; break; } return;}/* Last row and column computer moved to */- (int) lastRow{ return last_move_row;}- (int) lastColumn{ return last_move_col;}@end@implementation MainBoard- (id) initWithMatrix: (NSMatrix *)m{ self = [super init]; ASSIGN (matrix, m); size = [m numberOfRows]; board = [Board newWithRows: size ]; [self newGame]; return self;}- (void) dealloc{ RELEASE (matrix); RELEASE (board); [super dealloc];}- (void) newGame{ int i, j; /* Reset board */ [board reset]; for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { [self setTile: nothing inRow: i column: j]; } } turnsPlayed = 0; /* Answer to user input */ isGameActive = YES;}- (BOOL) isFreeRow: (int) i column: (int) j{ if ([board tileInRow: i column: j] == nothing) return YES; else return NO;}- (void) userMoveInRow: (int) i column: (int) j{ patternPosition pos; if (isGameActive == NO) return; if ([board tileInRow: i column: j] != nothing) return; [board setTile: human inRow: i column: j]; [self setTile: human inRow: i column: j]; pos = [board scanBoardForPattern: humanWonPattern length: 5]; if (PATTERN_FOUND (pos)) { // Human won int a, i, j; isGameActive = NO; i = pos.startRow; j = pos.startColumn; for (a = 0; a < 5; a++) { [self setWinningTile: human inRow: i column: j]; i += pos.directionRow; j += pos.directionColumn; } [self panel: _(@"Game Over") info: _(@"Great! You win!")]; return; } // NB: Human plays first, and the number of available squares is // even, so that if we are here, there still is a void square. [board performComputerMove]; [self setTile: computer inRow: [board lastRow] column: [board lastColumn]]; pos = [board scanBoardForPattern: computerWonPattern length: 5]; if (PATTERN_FOUND (pos)) { // Computer won int a, i, j; isGameActive = NO; i = pos.startRow; j = pos.startColumn; for (a = 0; a < 5; a++) { [self setWinningTile: computer inRow: i column: j]; i += pos.directionRow; j += pos.directionColumn; } [self panel: _(@"Game Over") info: _(@"Sorry, you loose.")]; } turnsPlayed++; if (turnsPlayed >= ((size * size) / 2)) { isGameActive = NO; [self panel: _(@"Game Over") info: _(@"Quits")]; } }- (void) setDifficultyLevel: (int) i{ if ((i >=0) && (i <= 5)) { difficultyLevel = i; [board setDifficultyLevel: i]; } else { NSLog (_(@"Internal Error: unknown difficultyLevel")); }}- (int) difficultyLevel{ return difficultyLevel;}/* * Methods used to display the board. * Override/rewrite the following methods to port the game * to another GUI framework. */// Change contents of (row i, column j) to display tile t (which can// be nothing, computer or human, see enum above)- (void) setTile: (tile) t inRow: (int) i column: (int) j{ NSImageCell *cell; NSRect rect; NSString *position; NSString *imageName; /* Determine the position of the cell */ position = @""; if (i == 0) { position = @"Top"; } else if (i == size - 1) { position = @"Bottom"; } if (j == 0) { position = [NSString stringWithFormat: @"%@Left", position]; } else if (j == size - 1) { position = [NSString stringWithFormat: @"%@Right", position]; } switch (t) { case human: imageName = [NSString stringWithFormat: @"Human%@", position]; break; case computer: imageName = [NSString stringWithFormat: @"Computer%@", position]; break; case nothing: default: imageName = [NSString stringWithFormat: @"Empty%@", position]; break; } cell = [matrix cellAtRow: i column: j]; [cell setImage: [NSImage imageNamed: imageName]]; rect = [matrix cellFrameAtRow: i column: j]; [matrix setNeedsDisplayInRect: rect];}// Change contents of (row i, column j) to display a winning tile of// type t (which can be nothing, computer or human, see enum above).// This is invoked when one the two players win, to highlight the// winning combination.- (void) setWinningTile: (tile) t inRow: (int) i column: (int) j{ // TODO}// Display an alert to the user through a pop up panel; typically// invoked as: [self panel: @"Game Over" info: @"Human won"];- (void) panel: (NSString *)s info: (NSString *)t{ NSRunAlertPanel (s, t, _(@"OK"), NULL, NULL);}@end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -