def create_minefield(self, form): if self.easy_rbtn.isChecked(): mode = (8, 8, 16) elif self.medium_rbtn.isChecked(): mode = (16, 16, 40) elif self.hard_rbtn.isChecked(): mode = (16, 30, 99) elif self.custom_rbtn.isChecked(): mode = 4 else: mode = 5 if mode == 5: self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Information) self.msg.setText("Please, select the mode") self.msg.setStandardButtons(QMessageBox.Ok) self.msg.exec_() elif mode == 4: pass else: form.hide() self.minefield = Minefield(mode) self.minefield.close_btn.clicked.connect( lambda: self.destroy_minefield(form)) self.minefield.show()
def __init__(self, processor): self.procr = processor for s in ['x_size', 'y_size', 'nr_mines', 'diff']: setattr(self, s, getattr(self.procr, s)) # Initialise the game board (all cells unclicked) self.board = [] for j in range(self.y_size): self.board.append(self.x_size * ['U']) # Instantiate a new minefield self.mf = Minefield(self.x_size, self.y_size) self.state = Game.READY self.start_time = None
def game(): m = Minefield.new_game() m.welcome() actions = { ('r', 'reveal'): m.select, ('u', 'unflag'): m.unflag, ('f', 'flag'): m.flag } exit_options = ('quit', 'exit', 'q') command = None while command not in exit_options and not m.game_over: print(m) location = input("Enter X, Y Coord. >? ") x, y = tuple(map(int, location.split(','))) coord = y, x action = input("Enter action (f)lag (u)nflag or (r)eveal").lower() for opts, func in actions.items(): if action in opts: func(coord) break else: print("No such command.") continue if m.check_win(): print("You win!")
def get_rem_3bv(self): """Calculate the minimum remaining number of clicks needed to solve.""" if self.state == Game.WON: return 0 elif self.state == Game.READY: return self.mf.bbbv else: t = tm.time() lost_mf = Minefield(auto_create=False, **self.settings) lost_mf.mine_coords = self.mf.mine_coords # Replace any openings already found with normal clicks (ones). lost_mf.completed_grid = np.where(self.grid < 0, self.mf.completed_grid, 1) # Find the openings which remain. lost_mf.get_openings() rem_opening_coords = [ c for opening in lost_mf.openings for c in opening ] # Count the number of essential clicks that have already been # done by counting clicked cells minus the ones at the edge of # an undiscovered opening. completed_3bv = len({ c for c in where_coords(self.grid >= 0) if c not in rem_opening_coords }) return lost_mf.get_3bv() - completed_3bv
class StartForm(Ui_Form): def __init__(self, form): self.setupUi(form) self.center(form) # self.ok_btn.clicked.connect(self.create_minefield) self.ok_btn.clicked.connect(lambda: self.create_minefield(form)) form.show() def center(self, form): qr = form.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) form.move(qr.topLeft()) def create_minefield(self, form): if self.easy_rbtn.isChecked(): mode = (8, 8, 16) elif self.medium_rbtn.isChecked(): mode = (16, 16, 40) elif self.hard_rbtn.isChecked(): mode = (16, 30, 99) elif self.custom_rbtn.isChecked(): mode = 4 else: mode = 5 if mode == 5: self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Information) self.msg.setText("Please, select the mode") self.msg.setStandardButtons(QMessageBox.Ok) self.msg.exec_() elif mode == 4: pass else: form.hide() self.minefield = Minefield(mode) self.minefield.close_btn.clicked.connect( lambda: self.destroy_minefield(form)) self.minefield.show() def destroy_minefield(self, form): #self.minefield.setParent(None) del self.minefield form.show()
def reset(self): """ Reset the Level """ self.completionRating = CompletionRating(self) self.moveRating = MoveRating(self) self.powerRating = PowerRating(self.getPowerRating(), self) self.minefield = Minefield(self.rows, self.columns) self.drone = Drone(self.minefield, self.moveRating, self.powerRating) self.defenseItems = [] for defenseClass in self.defenses: for i in range(self.defenses[defenseClass]): self.addDefense(defenseClass)
def random(): field = Minefield(*MINEFIELD_PARAM) shape = field.get_size() return field, shape
class Game: """Store attributes of a game such as the minefield, the start and end time etc.""" READY = 'ready' ACTIVE = 'active' LOST = 'lost' WON = 'won' def __init__(self, processor): self.procr = processor for s in ['x_size', 'y_size', 'nr_mines', 'diff']: setattr(self, s, getattr(self.procr, s)) # Initialise the game board (all cells unclicked) self.board = [] for j in range(self.y_size): self.board.append(self.x_size * ['U']) # Instantiate a new minefield self.mf = Minefield(self.x_size, self.y_size) self.state = Game.READY self.start_time = None def __repr__(self): if self.start_time: return "<Game object, started at {}>".format( tm.strftime('%H:%M, %d %b %Y', tm.localtime(self.start_time))) else: return "<Game object (not started)>" def __str__(self): ret = "Game:\n" + str(self.mf) if self.start_time: time = tm.strftime('%H:%M, %d %b %Y', tm.localtime(self.start_time)) ret += f"\nStarted at {time}." return ret def print_board(self): replace = {0: '-', 'U': '#'} if self.per_cell == 1: for char in ['M', 'F', '!', 'X', 'L']: replace[char + '1'] = char print(prettify_grid(self.board, replace)) def start_game(self, safe_coords=[]): for s in ['first_success', 'drag_select', 'per_cell']: setattr(self, s, getattr(self.procr, s)) self.mf.create(self.nr_mines, self.per_cell, safe_coords) self.state = Game.ACTIVE self.start_time = tm.time() def finalise(self): assert self.state in [Game.WON, Game.LOST], "Can't finalise until game is over" self.end_time = tm.time() self.elapsed = self.end_time - self.start_time def get_highscore(self): h = { 'name': self.procr.name, 'time': round(self.elapsed * 1000), '3bv': self.mf.get_3bv(), 'date': int(self.end_time), 'flagging': 'F' if bool(self.procr.nr_flags) else 'NF' } h['key'] = enchs(self, h) return h #[Check the following methods] def get_rem_3bv(self): """Calculate the minimum remaining number of clicks needed to solve.""" if self.state == Game.WON: return 0 elif self.state == Game.READY: return self.mf.bbbv else: t = tm.time() lost_mf = Minefield(auto_create=False, **self.settings) lost_mf.mine_coords = self.mf.mine_coords # Replace any openings already found with normal clicks (ones). lost_mf.completed_grid = np.where(self.grid < 0, self.mf.completed_grid, 1) # Find the openings which remain. lost_mf.get_openings() rem_opening_coords = [ c for opening in lost_mf.openings for c in opening ] # Count the number of essential clicks that have already been # done by counting clicked cells minus the ones at the edge of # an undiscovered opening. completed_3bv = len({ c for c in where_coords(self.grid >= 0) if c not in rem_opening_coords }) return lost_mf.get_3bv() - completed_3bv def get_prop_complete(self): """Calculate the progress of solving the board using 3bv.""" return float(self.mf.bbbv - self.get_rem_3bv()) / self.mf.bbbv def get_3bvps(self): """Return the 3bv/s.""" if self.start_time: return (self.mf.bbbv * self.get_prop_complete() / self.get_time_passed())
def play(human=False, show=True, minefield_param=MINEFIELD_PARAM): #by default runs as computer version #initializes screen if "show" chosen if show: pygame.init pygame.font.init() screen = pygame.display.set_mode(SIZE) pygame.display.set_caption("Blatant Minesweeper Copy") clock = pygame.time.Clock() field = Minefield(*minefield_param) shape = field.get_size() # shape of the minefield # prepares the rectangles if show: square_size, square_pos = square_size_position(shape, SIZE) rectdict = {} rectangles_todraw = [] for i in range(shape[0]): for j in range(shape[1]): pos = square_pos + (np.asarray((i, j)) * square_size) rectangle = pygame.Rect(pos[0], pos[1], int(square_size * (1 - SQ_SPACING)), int(square_size * (1 - SQ_SPACING))) rectdict[(i, j)] = rectangle rectangles_todraw.append( (screen, BLACK, rectangle, LINE_WIDTH)) done = False lost = False won = False update = False flagged = [] # list of flagged coordinates guessed = [] # list of guessed coordinates numbers_todraw = [] mines = field.get_mines() squares = shape[0] * shape[1] knowledge = np.full(shape, -1) '''knowledge is the array that is fed into the AI: -1 is not guessed, otherwise the value ''' if show: printscreen(screen, flagged, rectangles_todraw, numbers_todraw, rectdict, mines, guessed) while not done: #when computer, check if user wants to quit if show and not human: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True #get guess, either for human or computer if human: guesstype, guesscoord = eventhandler_human(rectdict) if guesstype == -1: done = True else: prob_mine = float(mines) / (squares - len(guessed)) guesstype, guesscoord = eventhandler_ai(knowledge, prob_mine, flagged) #guesstype, guesscoord = 1, (np.random.randint(0,shape[0]), np.random.randint(0,shape[1])) # process left click if guesstype == 1: if guesscoord in guessed: ''' if not human: lost = True done = True break ''' continue toprocess = [guesscoord] while True: if len(toprocess) != 0: guesscoord = toprocess[0] toprocess.remove(guesscoord) if guesscoord in flagged: flagged.remove(guesscoord) guessed.append(guesscoord) value = field.guess(*guesscoord) knowledge[guesscoord] = value if value == -1: lost = True done = True if show: rect = rectdict[guesscoord] rectangles_todraw.append((screen, BLACK, rect, 0)) update = True break elif show: rect = rectdict[guesscoord] number = pygame.font.Font( None, int(square_size * (1 - SQ_SPACING)) - LINE_WIDTH) image = number.render(str(value), True, BLACK) numbers_todraw.append( (image, (rect.center[0] + 1 - image.get_width() / 2, rect.center[1] + 1 - image.get_height() / 2))) update = True if value == 0: for i in range(-1, 2): for j in range(-1, 2): newx = i + guesscoord[0] newy = j + guesscoord[1] if newx < 0 or newy < 0 or newx >= shape[ 0] or newy >= shape[1]: continue if (newx, newy) not in guessed and ( newx, newy) not in toprocess: toprocess.append((newx, newy)) if len(toprocess) == 0: break # process right click elif guesstype == 3: if guesscoord in flagged: flagged.remove(guesscoord) update = True elif guesscoord not in guessed: flagged.append(guesscoord) update = True # updates the screen if update and show: printscreen(screen, flagged, rectangles_todraw, numbers_todraw, rectdict, mines, guessed) update = False #checks if won if squares - len(guessed) == mines: won = True done = True # ticks if human: clock.tick(60) elif show: clock.tick(COMPUTERSPEED) #print messages for winning and losing if lost and show: done = False text = pygame.font.Font(None, int(.3 * SIZE[1])) image = text.render("You lost!", True, SKY_BLUE) screen.blit(image, (SIZE[0] / 2 - image.get_width() / 2, SIZE[1] / 2 - image.get_height() / 2)) pygame.display.update() print("You lost!") elif won and show: done = False text = pygame.font.Font(None, int(.3 * SIZE[1])) image = text.render("You won!", True, SKY_BLUE) screen.blit(image, (SIZE[0] / 2 - image.get_width() / 2, SIZE[1] / 2 - image.get_height() / 2)) pygame.display.update() print("You won!") # if human player, doesn't automatically close the window if show: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True while not done and human: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True if not human and show: time.sleep(1) if not human and not lost and not won: return -1, False # returns the score if not human: return len(guessed), won