def get_displayed_numbers(self): """Put the displayed numbers in a dictionary with coordinate as key, storing their neighbouring clickable cells.""" self.numbers = dict() edge_coords = set() # Look through all the cells to find the revealed numbers for (x, y) in self.all_coords: contents = self.board[y][x] if type(contents) is str or contents == 0: continue nr = contents nbrs = get_nbrs(x, y, self.x_size, self.y_size) clickable_nbrs = [] for (i, j) in nbrs: c = self.board[j][i] if str(c)[0] in ['F', 'L']: nr -= int(c[1]) elif str(c)[0] in ['U', 'M']: # Include displayed mines for state before game was lost clickable_nbrs.append((i, j)) edge_coords.update(clickable_nbrs) # Check number isn't too high for the available space if nr > len(clickable_nbrs) * self.max_per_cell: msg = "Error: number {} in cell {} is too high" raise ValueError(msg.format(contents, (x, y))) clickable_nbrs.sort() # To help with debugging self.numbers[(x, y)] = { 'nr': nr, 'nbrs': clickable_nbrs, 'groups': [] } # All coords that are clickable and next to a number self.edge_coords = sorted(list(edge_coords))
def click(self, x, y, check_for_win=True): if self.game.board[y][x] != 'U': return if self.game.state == Game.READY: safe_coords = (get_nbrs(x, y, self.x_size, self.y_size) if self.first_success else []) self.game.start_game(safe_coords) self.ui.start_game() cell = self.game.mf.completed_board[y][x] if type(cell) is str: # Mine hit, game over self.game.board[y][x] = '!' + str(self.game.mf[y][x]) # self.ui.reveal_cell(x, y) self.finalise_loss() return # No need to check for win elif cell == 0: # Opening hit for opening in self.game.mf.openings: if (x, y) in opening: break # Work with this set of coords for (x, y) in opening: if self.game.board[y][x] == 'U': self.game.board[y][x] = self.game.mf.completed_board[y][x] self.ui.reveal_cell(x, y) else: # Number revealed self.game.board[y][x] = self.game.mf.completed_board[y][x] self.ui.reveal_cell(x, y) if check_for_win and self.check_is_game_won(): self.finalise_win()
def get_completed_board(self): for (x, y) in self.all_coords: mines = self[y][x] if mines > 0: # print((x, y)) self.completed_board[y][x] = 'F' + str(mines) # print(prettify_grid(self.completed_board)) for (i, j) in get_nbrs(x, y, self.x_size, self.y_size): # print(" ", (i, j), self[j][i]) if self[j][i] == 0: self.completed_board[j][i] += mines
def get_openings(self): self.openings = [] all_found = set() for (x, y) in self.all_coords: coord = (x, y) if self.completed_board[y][x] == 0 and coord not in all_found: opening = set([coord]) check = set([coord]) while check: c = check.pop() nbrs = set(get_nbrs(c[0], c[1], self.x_size, self.y_size)) check |= {(i, j) for (i, j) in nbrs - opening if self.completed_board[j][i] == 0} opening |= nbrs self.openings.append(sorted(opening)) all_found |= opening
def chord(self, x, y): """Receive an attempt to chord at (x, y). If the number of flags is correct, return True and send the required signals to the UI, otherwise return False.""" state = self.game.board[y][x] if type(state) is not int: return False nbrs = get_nbrs(x, y, self.x_size, self.y_size) nbr_flags = sum([ int(self.game.board[j][i][1]) for (i, j) in nbrs if str(self.game.board[j][i])[0] in ['F', 'L'] ]) if nbr_flags == state: for (i, j) in nbrs: if self.game.board[j][i] == 'U': self.click(i, j, check_for_win=False) if self.check_is_game_won(): self.finalise_win() # self.ui.reveal_cell(i, j) return True else: return False
def raise_area(self, x, y): for (i, j) in get_nbrs(x, y, self.x_size, self.y_size): self.buttons[j][i].areaReleased.emit()
def sink_area(self, x, y): for (i, j) in get_nbrs(x, y, self.x_size, self.y_size): self.buttons[j][i].areaPressed.emit()