def AlgoFullRandom(cls, debug=False): import random agent = Minesweeper(1, 1, cls.size) while len(agent): if debug: print agent agent.step(*random.choice(agent.safeStep))
def AlgoSimpleStrategy(cls, debug=False, default=0.3): def ratio(cls, x, y): fn = lambda x, y: cls[x, y]/float(cls.empty(x, y)) nr = [[_x, _y] for _x in range(x-1, x+2) for _y in (y-1, y+1) if 0 < cls[_x, _y]] nr += [[_x, y] for _x in (x-1, x+1) if 0 < cls[_x, y]] if nr: return max([fn(*_) for _ in nr]) else: return default agent = Minesweeper(1, 1, cls.size, debug=debug) while len(agent): if debug: print agent, len(agent) steps = [[_, ratio(agent, *_)] for _ in agent.safeStep] steps = sorted(steps, key=lambda x: x[1]) agent.step(*steps[0][0])
def test(density): size = 30 total_score = 0 total_choice = 0 num_tests = 100 density_v_score = [] density_v_average = [] for i in range(num_tests): game = Minesweeper(size, int((size**2) * density)) game_full_update(game) score = basic_agent(game, improved_min_risk) total_choice += decision_func_counter total_score += score score = total_score / num_tests average = total_choice / num_tests print("Improved Min Risk " + str(density) + "\n" "Density VS Score -- " + str(density) + "\n" + str(density) + ", " + str(score) + "\n" + "Density VS Average Risk -- " + str(density) + "\n" + str(density) + ", " + str(average) + "\n") total_score = 0 total_choice = 0 pygame.quit() quit()
def test_query_view_the_board(self): minesweeper = Minesweeper() minesweeper.new_game() board = minesweeper.view_board() # by default, board initialises to 10 x 10 tiles # unrevealed tiles are marked by spaces ' ' self.assertEqual(board, [ [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], ])
def __init__( self, row_count=8, col_count=8, activity_mode="game", total_bomb_count=10, seed=randint(0, 100), bomb_locations=[], board=[], ): Minesweeper.__init__( self, row_count, col_count, activity_mode, total_bomb_count, seed, bomb_locations, board, ) self.make_prob_board() self.update_prob_board() self.check_for_contradictions() while self.game_over_state == 0: print("Executing AI strategy") self.make_prob_board() self.update_prob_board() self.probability_nearby() self.go_through_what_ifs() self.probability_not_nearby() self.print_prob_board() assert not self.check_for_contradictions( verbose=True), "CONTRADICTION DETECTED" self.ai_next_move()
def init(gridsize, no_mines): global minesweeper global aiBoard global GRIDSIZE global NO_MINES global statistics minesweeper = Minesweeper(gridsize, no_mines) aiBoard = AIBoard(gridsize) GRIDSIZE = gridsize NO_MINES = no_mines
def __init__(self, load_game=None): self.rows = 16 self.columns = 30 self.num_mines = 99 if load_game is None: self.mine = Minesweeper(self.rows, self.columns, self.num_mines, gui=False) else: self.mine = Minesweeper.load_state(load_game) self.servant = MineServant(self.mine) self.exposed_indices = self.mine.exposed_field # Move these to self.exposed_field self.newly_exposed = [] # Add block indices to here as they're revealed self.unchecked_blocks = [] # Blocks scheduled to be removed after some processes for loops self.blocks_to_remove = set([]) self.flags_planted = 0 # Lose/win status. Both start as false naturally self.lose = False self.win = False self.semi_solver = None
def create_hidden_and_button_board(self, length, height, mines): """It creates a new Minesweeper grid.""" self.list_buttons = [] self.game = Minesweeper() self.game.create_board(length, height, mines) self.game.board.create_random_grid() self.game.board.change_0s_to_blank_spaces() # CREATE GRID FRAME self.frame_grid = tk.Frame(self.frame_whole_window) self.frame_grid.grid(row=1, column=0, padx=5, pady=10) self.frame_grid.config(background='#C0C0C0') # Creates board seen by the user for i, tile in enumerate(self.game.board.tiles): column = i % self.game.board.grid_size[1] row = i // self.game.board.grid_size[1] photo = self.image_full_tile btn = SpecialButton( self.frame_grid, tile=tile, text=str(tile.appearance), rrow=row, ccolumn=column, image=photo, app=self, ) btn.grid(row=row, column=column) self.list_buttons.append(btn) # Reset Smiley self.smiley_button['image'] = self.image_smiley # Reset Timer self.time = 0 self.timer_status = False
def __init__(self, load_game=None): self.rows = 16 self.columns = 30 self.num_mines = 99 if load_game is None: self.mine = Minesweeper(self.rows, self.columns, self.num_mines, gui=False) else: self.mine = Minesweeper.load_state(load_game) self.servant = MineServant(self.mine) self.exposed_indices = self.mine.exposed_field # Move these to self.exposed_field self.newly_exposed = [] # Add block indices to here as they're revealed self.unchecked_blocks = [] # Blocks scheduled to be removed after some processes for loops self.blocks_to_remove = set([]) self.flags_planted = 0 # Lose/win status. Both start as false naturally self.lose = False self.win = False self.semi_solver = None
def test(n, s, m): lossCount_CSP = 0 winCount_CSP = 0 start = time.time() # Run tests i = 0 while i < n: # Create the Minesweeper (both for CSP and RL) new_minesweeper = Minesweeper(width=s, height=s, mines=m) winCount_CSP, lossCount_CSP = game_as_CSP(new_minesweeper, winCount_CSP, lossCount_CSP, s) i += 1 end = time.time() overall_time = end - start print("\n\n") print("Results of running CSP on {} puzzles: \n".format(n)) print("CSP success rate: {}".format(winCount_CSP / n)) print("CSP avg game time: {}".format(overall_time / n))
async def _start(ctx, width=10, height=10, mines=None): if mines == None: mines = (width * height) // 10 else: mines = int(mines) if "minesweeper" in ctx.channel.name or str( ctx.channel.id) in minesweeperChannel.get(str(ctx.guild.id), []): pass else: await ctx.send( "Minesweeper is not enabled in this channel, use `ms!addChannel #channel` to enable minesweeper for `#channel`" ) return if mines > width * height: await ctx.send("Too many mines for a minefield of this size!") return if width > 26: await ctx.send("Width limit exceeded(max 26)") return if height > 50: await ctx.send("Height limit exceeded(max 50)") return minefield = Minesweeper(width, height, mines, ctx) embed = discord.Embed( title="Minesweeper", description="Flags left: {nFlags}".format(nFlags=mines)) filename = str(minefield) embed.set_image(url="attachment://{filename}".format(filename=filename)) embed.set_footer(text=ctx.author.display_name, icon_url=ctx.author.avatar_url) file = discord.File("{filename}".format(filename=filename)) games[str(ctx.author.id)] = { "gameObject": minefield, "message": await ctx.send(file=file, embed=embed), "timeStart": time.time() }
def test_command_toggle_mine_marking(self): minesweeper = Minesweeper() minesweeper.new_game() minesweeper.toggle_mine_marking({'row': 0, 'col': 0})
# same process as Iterate through list of neighboring cells # 5-If player uncovers all non-mine cells --> # set game state to win, print winner message # prompt player to play again # if yes --> set game state to 'playing' # if no --> end program from Minesweeper import Minesweeper #Initial value is set to playing game_state_str = "playing" while game_state_str == "playing": #Create Minesweeper object and assign to variable game game = Minesweeper() #Populate all objects required to play game game.populate_values() #Display player board to player game.displayPlayer_Board(game.player_board) #Prompt player to enter cell to uncover on minesweeper board. userinput_message_str = "Select the Cell you want to uncover." userinput_message_str2 = "Enter Row Number of Cell: " userinput_message_str3 = "Enter Column Number of Cell: " userinput_str = "" valid_input_list = ["1","2","3","4","5"] print(userinput_message_str) validinput_bool = True while validinput_bool == True:
from views.game import * from Minesweeper import Minesweeper while True: op = selection_menu() if op == '1': game = Minesweeper() # an invalid position row, column = -1, -1 status = Minesweeper.GAMING while status == Minesweeper.GAMING: game.make_moviment(row, column) status = game.get_status(row, column) show_formatted_grid(game, status) if status == Minesweeper.GAME_OVER: show_end_message('VOCÊ PERDEU!') elif status == Minesweeper.GAME_WIN: show_end_message('VOCÊ VENCEU!!!') else: row, column = get_coordinates() elif op == '2': # sair break
@author: apple """ from Minesweeper import Minesweeper win = 0 lose = 0 while True: height = int(input('Enter a height: ')) length = int(input('Enter a length: ')) bomb = int(input('Enter the number of bombs: ')) while bomb > height * length: print('Invalid Input') height = int(input('Enter a height: ')) length = int(input('Enter a length: ')) bomb = int(input('Enter the number of bombs: ')) minesweeper = Minesweeper(height, length, bomb) #minesweeper._getSolution() minesweeper.printBoard() x = int(input('Select an x coordinate: ')) y = int(input('Select an y coordinate: ')) while not minesweeper.checkValid(y, x): print('Invalid Input') x = int(input('Select an x coordinate: ')) y = int(input('Select an y coordinate: ')) minesweeper.selectFirst(y, x) minesweeper.printBoard() if minesweeper.isWin(): win = win + 1 print('You win') again = input('Do you want to play again ("yes" or "no")? ') if again == 'yes':
import time import random import PySimpleGUI as gui from PySimpleGUI.PySimpleGUI import WINDOW_CLOSED from Minesweeper import Minesweeper, MinesweeperStatus # Get all arguments input from test case size = int(input()) bombs = int(input()) locations = [list(map(int, input().split(', '))) for _ in range(bombs)] # Create new minesweeper object minesweeper = Minesweeper(locations=locations, size=size, bombs=bombs) is_initialized = False is_manual = False # Initialize all GUI components gui.theme('DarkAmber') layout = [ [gui.Text('Minesweeper', font=('Roboto', 24), justification='center')], *[[gui.Button(key=f'tile_{i}_{j}', size=(2, 2), pad=(0, 0), font=('Roboto', 12)) for j in range(minesweeper.size)] for i in range(minesweeper.size)], [gui.Button('Step', disabled=False, key="-step-"), gui.Button( 'Manual Toggle', key="-manual-"), gui.Button('Simulate', key='-simulate-')] ] # Generate window application window = gui.Window('Minesweeper', layout) # Lose and Win Random Messages
def create_standard_grid(): game = Minesweeper() game.create_board(3, 3, 1) game.board.create_random_grid() game.board.change_0s_to_blank_spaces() return game
def test_query_time_elapsed(self): minesweeper = Minesweeper() minesweeper.new_game() self.assertEqual(minesweeper.time_elapsed(), 0)
def test_command_create_a_new_game(self): minesweeper = Minesweeper() minesweeper.new_game()
def test_query_game_status(self): minesweeper = Minesweeper() minesweeper.new_game() self.assertEqual(minesweeper.status(), 'Playing')
class MineSolver: """ Solves Minesweeper by running through a few algorithms: Flag/reveal Confined Mine Shared Mine """ def __init__(self, load_game=None): self.rows = 16 self.columns = 30 self.num_mines = 99 if load_game is None: self.mine = Minesweeper(self.rows, self.columns, self.num_mines, gui=False) else: self.mine = Minesweeper.load_state(load_game) self.servant = MineServant(self.mine) self.exposed_indices = self.mine.exposed_field # Move these to self.exposed_field self.newly_exposed = [] # Add block indices to here as they're revealed self.unchecked_blocks = [] # Blocks scheduled to be removed after some processes for loops self.blocks_to_remove = set([]) self.flags_planted = 0 # Lose/win status. Both start as false naturally self.lose = False self.win = False self.semi_solver = None def reveal_squares(self, coordinate): """ Calls the Minesweeper button_reveal function so progress can be tracked with the GUI. :param coordinate: :return: """ for coord in coordinate: self.lose, self.newly_exposed = self.mine.button_reveal( None, coord) self.unchecked_blocks.extend(self.newly_exposed) def logical_solver(self): """ Process that loops through unchecked blocks and runs the flag/reveal process. :return: """ # Will break out if no moves found solver_repeat = True while solver_repeat: # Try the easy stuff solver_repeat = self.flag_reveal_loop() # Now try the hard stuff for coordinate in self.unchecked_blocks: unrevealed = self.servant.get_unrevealed_blocks(coordinate) if unrevealed: area_reveal, area_flag = self.confined_mine_process( coordinate, unrevealed) if self.lose: print "Somehow we lost?! It's your fault." return # Break out of hard stuff and go to flag/reveal if area_reveal or area_flag: solver_repeat = True break # Check for a shared mine shared_reveal, shared_flag = self.shared_mine_process( coordinate) if self.lose: print "Somehow we lost?! It's your fault." return if shared_reveal or shared_flag: solver_repeat = True break # Schedule block for deletion after for loop. else: self.blocks_to_remove.add(coordinate) if self.blocks_to_remove: self.remove_checked_blocks() print "Out of moves. Full field:" # Quasi pretty-prints the field for the console. self.servant.pretty_print_field() if self.win: print "You won, because you're the best maybe." def probability_guesser(self): """ :return: """ # Get all unrevealed blocks that touch unchecked blocks blocks_to_guess = set([]) numbers_dictionary = {} for coordinate in self.unchecked_blocks: numbers_dictionary[coordinate] = self.servant.get_real_block_value( coordinate) unrevealed_blocks = self.servant.get_unrevealed_blocks(coordinate) blocks_to_guess.update(unrevealed_blocks) # self.servant.custom_pretty_print_field(self.exposed_field, blocks_to_guess) self.semi_solver = MineSemiSolver(blocks_to_guess, numbers_dictionary, self.rows, self.columns) self.semi_solver.choose() # self.servant.custom_pretty_print_field(self.exposed_field, unrevealed=blocks_to_guess) def remove_checked_blocks(self): """ Removes self.blocks_to_remove from self.exposed_field. :return: """ for block in self.blocks_to_remove: self.unchecked_blocks.remove(block) self.blocks_to_remove.clear() def flag_reveal_loop(self): """ A loop to call flag_reveal_process in an efficient manner. :return: """ solver_repeat = False flag_reveal_repeat = True # Do the easy stuff first while flag_reveal_repeat: # Will break out if no flag or reveal flag_reveal_repeat = False for coordinate in self.unchecked_blocks: # Check if there are any unrevealed blocks unrevealed = self.servant.get_unrevealed_blocks(coordinate) if unrevealed: reveal, flag = self.flag_reveal_process( coordinate, unrevealed) # If it hits even once, repeat flag/reveal if reveal or flag: flag_reveal_repeat = True if self.lose: print "Somehow we lost?! It's your fault." return # If not, schedule block for deletion after for loop. else: self.blocks_to_remove.add(coordinate) # Remove blocks before moving on if self.blocks_to_remove: self.remove_checked_blocks() if self.win: solver_repeat = False break return solver_repeat def flag_reveal_process(self, coordinate, unrevealed): """ Main process in which unrevealed blocks are found to reveal or flag. :param coordinate: :return: """ reveal = False flag = False num_unrevealed = len(unrevealed) real_block_value = self.servant.get_real_block_value(coordinate) # All mines accounted for. Reveal rest if real_block_value == 0: self.reveal_squares(unrevealed) self.blocks_to_remove.add(coordinate) reveal = True # All unrevealed are mines. Flag them elif real_block_value == num_unrevealed: for coord in unrevealed: self.win = self.mine.button_flag(None, coord) self.flags_planted += 1 self.blocks_to_remove.add(coordinate) flag = True return reveal, flag def confined_mine_process(self, coordinate, unrevealed): """ Check if a mine is enclosed in an area, and if surrounding blocks can be flagged or revealed. :param coordinate: :return: """ reveal = False flag = False mines_in_area = self.servant.get_real_block_value(coordinate) # starts with first block, then whittles down similar_neighbors = set( self.servant.get_exposed_neighbor_coords(unrevealed[0])) for block in unrevealed[1:]: # gets the neighbors of the next block block_neighbors = self.servant.get_exposed_neighbor_coords(block) similar_neighbors.intersection_update(block_neighbors) # Now we have a list of shared neighbors. We need to check them all. for neighbor in similar_neighbors: real_block_value = self.servant.get_real_block_value(neighbor) # starts as full blocks_out_of_area = set( self.servant.get_unrevealed_blocks(neighbor)) # Gets rid of blocks in unrevealed blocks_out_of_area.difference_update(unrevealed) num_outside = len(blocks_out_of_area) if num_outside > 0: # Flag blocks outside of area. if real_block_value == num_outside + mines_in_area: for block in blocks_out_of_area: self.win = self.mine.button_flag(None, block) self.flags_planted += 1 flag = True # Reveal blocks outside area if real_block_value == mines_in_area: self.reveal_squares(blocks_out_of_area) reveal = True return reveal, flag def shared_mine_process(self, coordinate): """ Loop through all neighbors and check if they share mines. :return: """ flag = False reveal = False neighbor_blocks = self.servant.get_neighbor_blocks(coordinate) real_block_value = self.servant.get_real_block_value(coordinate) # Loops through all neighbors for neighbor in neighbor_blocks: # Don't do checked neighbors if neighbor not in self.unchecked_blocks: continue # Find shared unrevealed blocks blocks_unrevealed = set( self.servant.get_unrevealed_blocks(coordinate)) neighbor_unrevealed = set( self.servant.get_unrevealed_blocks(neighbor)) # Get all unrevealed blocks shared by the neighbors shared_unrevealed = blocks_unrevealed.intersection( neighbor_unrevealed) num_shared = len(shared_unrevealed) neighbor_real_block_value = self.servant.get_real_block_value( neighbor) possible_area_mines = min(real_block_value, neighbor_real_block_value, num_shared) neighbors_outside_area = len(neighbor_unrevealed) - num_shared if neighbors_outside_area > 0 and \ neighbor_real_block_value == neighbors_outside_area + possible_area_mines: # Flag neighbor blocks not shared with coordinate for block in neighbor_unrevealed.difference(blocks_unrevealed): self.win = self.mine.button_flag(None, block) self.flags_planted += 1 flag = True # Check if the original block can reveal things. if real_block_value == possible_area_mines: # Reveal blocks not shared with neighbor self.reveal_squares( blocks_unrevealed.difference(neighbor_unrevealed)) reveal = True return reveal, flag
for i in range(len(board[0])): column_label += horizontal_padding column_label += str(i) print(column_label) for vertical_index, row in enumerate(board): result = '' result += str(vertical_index) for col in row: result += horizontal_padding result += str(col) print(result) minesweeper = Minesweeper() minesweeper.new_game() print('Welcome to Minesweeper') print_commands() while minesweeper.status() == 'Playing': print('Game Status:', minesweeper.status()) print('Mines left:', minesweeper.mines_remaining()) print('Time Elapsed:', minesweeper.time_elapsed()) pretty_print_board(minesweeper.view_board()) process_input(input()) if minesweeper.status() == 'Lose': pretty_print_board(minesweeper.view_board()) print('Mines left:', minesweeper.mines_remaining()) print('Time Elapsed:', minesweeper.time_elapsed()) print('BOOM')
class MineSolver: """ Solves Minesweeper by running through a few algorithms: Flag/reveal Confined Mine Shared Mine """ def __init__(self, load_game=None): self.rows = 16 self.columns = 30 self.num_mines = 99 if load_game is None: self.mine = Minesweeper(self.rows, self.columns, self.num_mines, gui=False) else: self.mine = Minesweeper.load_state(load_game) self.servant = MineServant(self.mine) self.exposed_indices = self.mine.exposed_field # Move these to self.exposed_field self.newly_exposed = [] # Add block indices to here as they're revealed self.unchecked_blocks = [] # Blocks scheduled to be removed after some processes for loops self.blocks_to_remove = set([]) self.flags_planted = 0 # Lose/win status. Both start as false naturally self.lose = False self.win = False self.semi_solver = None def reveal_squares(self, coordinate): """ Calls the Minesweeper button_reveal function so progress can be tracked with the GUI. :param coordinate: :return: """ for coord in coordinate: self.lose, self.newly_exposed = self.mine.button_reveal(None, coord) self.unchecked_blocks.extend(self.newly_exposed) def logical_solver(self): """ Process that loops through unchecked blocks and runs the flag/reveal process. :return: """ # Will break out if no moves found solver_repeat = True while solver_repeat: # Try the easy stuff solver_repeat = self.flag_reveal_loop() # Now try the hard stuff for coordinate in self.unchecked_blocks: unrevealed = self.servant.get_unrevealed_blocks(coordinate) if unrevealed: area_reveal, area_flag = self.confined_mine_process(coordinate, unrevealed) if self.lose: print "Somehow we lost?! It's your fault." return # Break out of hard stuff and go to flag/reveal if area_reveal or area_flag: solver_repeat = True break # Check for a shared mine shared_reveal, shared_flag = self.shared_mine_process(coordinate) if self.lose: print "Somehow we lost?! It's your fault." return if shared_reveal or shared_flag: solver_repeat = True break # Schedule block for deletion after for loop. else: self.blocks_to_remove.add(coordinate) if self.blocks_to_remove: self.remove_checked_blocks() print "Out of moves. Full field:" # Quasi pretty-prints the field for the console. self.servant.pretty_print_field() if self.win: print "You won, because you're the best maybe." def probability_guesser(self): """ :return: """ # Get all unrevealed blocks that touch unchecked blocks blocks_to_guess = set([]) numbers_dictionary = {} for coordinate in self.unchecked_blocks: numbers_dictionary[coordinate] = self.servant.get_real_block_value(coordinate) unrevealed_blocks = self.servant.get_unrevealed_blocks(coordinate) blocks_to_guess.update(unrevealed_blocks) # self.servant.custom_pretty_print_field(self.exposed_field, blocks_to_guess) self.semi_solver = MineSemiSolver(blocks_to_guess, numbers_dictionary, self.rows, self.columns) self.semi_solver.choose() # self.servant.custom_pretty_print_field(self.exposed_field, unrevealed=blocks_to_guess) def remove_checked_blocks(self): """ Removes self.blocks_to_remove from self.exposed_field. :return: """ for block in self.blocks_to_remove: self.unchecked_blocks.remove(block) self.blocks_to_remove.clear() def flag_reveal_loop(self): """ A loop to call flag_reveal_process in an efficient manner. :return: """ solver_repeat = False flag_reveal_repeat = True # Do the easy stuff first while flag_reveal_repeat: # Will break out if no flag or reveal flag_reveal_repeat = False for coordinate in self.unchecked_blocks: # Check if there are any unrevealed blocks unrevealed = self.servant.get_unrevealed_blocks(coordinate) if unrevealed: reveal, flag = self.flag_reveal_process(coordinate, unrevealed) # If it hits even once, repeat flag/reveal if reveal or flag: flag_reveal_repeat = True if self.lose: print "Somehow we lost?! It's your fault." return # If not, schedule block for deletion after for loop. else: self.blocks_to_remove.add(coordinate) # Remove blocks before moving on if self.blocks_to_remove: self.remove_checked_blocks() if self.win: solver_repeat = False break return solver_repeat def flag_reveal_process(self, coordinate, unrevealed): """ Main process in which unrevealed blocks are found to reveal or flag. :param coordinate: :return: """ reveal = False flag = False num_unrevealed = len(unrevealed) real_block_value = self.servant.get_real_block_value(coordinate) # All mines accounted for. Reveal rest if real_block_value == 0: self.reveal_squares(unrevealed) self.blocks_to_remove.add(coordinate) reveal = True # All unrevealed are mines. Flag them elif real_block_value == num_unrevealed: for coord in unrevealed: self.win = self.mine.button_flag(None, coord) self.flags_planted += 1 self.blocks_to_remove.add(coordinate) flag = True return reveal, flag def confined_mine_process(self, coordinate, unrevealed): """ Check if a mine is enclosed in an area, and if surrounding blocks can be flagged or revealed. :param coordinate: :return: """ reveal = False flag = False mines_in_area = self.servant.get_real_block_value(coordinate) # starts with first block, then whittles down similar_neighbors = set(self.servant.get_exposed_neighbor_coords(unrevealed[0])) for block in unrevealed[1:]: # gets the neighbors of the next block block_neighbors = self.servant.get_exposed_neighbor_coords(block) similar_neighbors.intersection_update(block_neighbors) # Now we have a list of shared neighbors. We need to check them all. for neighbor in similar_neighbors: real_block_value = self.servant.get_real_block_value(neighbor) # starts as full blocks_out_of_area = set(self.servant.get_unrevealed_blocks(neighbor)) # Gets rid of blocks in unrevealed blocks_out_of_area.difference_update(unrevealed) num_outside = len(blocks_out_of_area) if num_outside > 0: # Flag blocks outside of area. if real_block_value == num_outside + mines_in_area: for block in blocks_out_of_area: self.win = self.mine.button_flag(None, block) self.flags_planted += 1 flag = True # Reveal blocks outside area if real_block_value == mines_in_area: self.reveal_squares(blocks_out_of_area) reveal = True return reveal, flag def shared_mine_process(self, coordinate): """ Loop through all neighbors and check if they share mines. :return: """ flag = False reveal = False neighbor_blocks = self.servant.get_neighbor_blocks(coordinate) real_block_value = self.servant.get_real_block_value(coordinate) # Loops through all neighbors for neighbor in neighbor_blocks: # Don't do checked neighbors if neighbor not in self.unchecked_blocks: continue # Find shared unrevealed blocks blocks_unrevealed = set(self.servant.get_unrevealed_blocks(coordinate)) neighbor_unrevealed = set(self.servant.get_unrevealed_blocks(neighbor)) # Get all unrevealed blocks shared by the neighbors shared_unrevealed = blocks_unrevealed.intersection(neighbor_unrevealed) num_shared = len(shared_unrevealed) neighbor_real_block_value = self.servant.get_real_block_value(neighbor) possible_area_mines = min(real_block_value, neighbor_real_block_value, num_shared) neighbors_outside_area = len(neighbor_unrevealed) - num_shared if neighbors_outside_area > 0 and \ neighbor_real_block_value == neighbors_outside_area + possible_area_mines: # Flag neighbor blocks not shared with coordinate for block in neighbor_unrevealed.difference(blocks_unrevealed): self.win = self.mine.button_flag(None, block) self.flags_planted += 1 flag = True # Check if the original block can reveal things. if real_block_value == possible_area_mines: # Reveal blocks not shared with neighbor self.reveal_squares(blocks_unrevealed.difference(neighbor_unrevealed)) reveal = True return reveal, flag
size = int( input( "Enter the size, for example enter 30 for a 30 x 30 grid\n" )) is_set = True except ValueError: print("Incorrect Entry") is_set = False while not is_set: try: num_mines = int(input("Enter the number of mines\n")) is_set = True except ValueError: print("Incorrect Entry") game = Minesweeper(size, num_mines) game_full_update(game) score = 0 if cfunc == 0: score = basic_agent(game, rand_choice) elif cfunc == 1: score = basic_agent(game, min_cost) elif cfunc == 2: score = basic_agent(game, min_risk) elif cfunc == 3: score = basic_agent(game, improved_min_risk) elif cfunc == 4: score = basic_agent(game, improved_min_cost) else: print("Quiting")
"""Program that allows a user to play Minesweeper on his terminal.""" from Minesweeper import Minesweeper if __name__ == '__main__': GAME = Minesweeper() GAME.start()
async def _multiplayer(ctx, *args): width = None height = None mines = None for i in range(3): if isInt(args[i]): if i == 0: width = int(args[i]) elif i == 1: height = int(args[i]) else: mines = int(args[i]) else: break if width == None: width = 10 if height == None: height = 10 if mines == None: mines = (width * height) // 10 if "minesweeper" in ctx.channel.name or str( ctx.channel.id) in minesweeperChannel.get(str(ctx.guild.id), []): pass else: await ctx.send( "Minesweeper is not enabled in this channel, use `ms!addChannel #channel` to enable minesweeper for `#channel`" ) return if mines > width * height: await ctx.send("Too many mines for a minefield of this size!") return if width > 26: await ctx.send("Width limit exceeded(max 26)") return if height > 50: await ctx.send("Height limit exceeded(max 50)") return if not ctx.message.mentions: await ctx.send("You haven't mentioned anyone to play with") return playercount = len(ctx.message.mentions) + 1 players = [str(ctx.author.id)] for usr in ctx.message.mentions: for game in mp_games: if str(usr.id) in game: if not mp_games[game]["gameObject"].gameOver: await ctx.send( "User has not yet finished their multiplayer game, use ms!leave to leave" ) return if games.get(str(usr.id), False): if not games[str(usr.id)]["gameObject"].gameOver or ( time.time() - games[str(usr.id)]["timeStart"]) < -3600: await ctx.send( "User has not yet finished their game, use ms!end to finish your game" ) return if str(usr.id) not in players: players.append(str(usr.id)) if len(players) == 1: await ctx.send( "Too few players, you can't play by yourself, use ms!start for a solo game" ) return players = tuple(players) minefield = Minesweeper(width, height, mines, ctx) embed = discord.Embed( title="Minesweeper", description="Flags left: {nFlags}".format(nFlags=mines)) filename = str(minefield) embed.set_image(url="attachment://{filename}".format(filename=filename)) embed.set_footer(text="{user}'s turn".format(user=ctx.author.display_name), icon_url=ctx.author.avatar_url) file = discord.File("{filename}".format(filename=filename)) mp_games[players] = { "gameObject": minefield, "message": await ctx.send(file=file, embed=embed), "timeStart": time.time(), "playercount": playercount, "nextPlayer": 0 }
from Minesweeper import Minesweeper game = Minesweeper() game.playMinesweeper(20, 50)
def test_query_mines_remaining(self): minesweeper = Minesweeper() minesweeper.new_game() self.assertEqual(minesweeper.mines_remaining(), 10)
class MinesweeperApp: """This class manages the UI for a Minesweeper game.""" def __init__(self): """Creates the initial window along with a random Minesweeper grid.""" # Create the behind the scenes board self.height = 9 self.length = 9 self.mines = 10 # Create window self.root = tk.Tk() self.root.wm_title("Minesweeper") self.root.iconbitmap("images/Minesweeper_Game_icon.ico") self.load_images() # Add menu self.menubar = tk.Menu(self.root) gamemenu = tk.Menu(self.menubar, tearoff=0) gamemenu.add_command(label='Settings', command=self.open_settings_window) self.menubar.add_cascade(label='Game', menu=gamemenu) helpmenu = tk.Menu(self.menubar, tearoff=0) helpmenu.add_command(label="You don't need help lol.", command=lambda: None) self.menubar.add_cascade(label='Help', menu=helpmenu) # Display Menu self.root.config(menu=self.menubar) # FRAME WHOLE WINDOW self.frame_whole_window = tk.Frame(self.root) self.frame_whole_window.grid() self.frame_whole_window.config(background='#C0C0C0') # FRAME OVER GRID self.frame_over_grid = tk.Frame(self.frame_whole_window) self.frame_over_grid.grid(row=0, column=0, padx=5, pady=5) self.frame_over_grid.config(background='#C0C0C0') # FRAME FLAG COUNT self.frame_flag_count = tk.Canvas(self.frame_over_grid, width=45, height=25) self.frame_flag_count.grid(row=0, column=0, sticky=tk.W, padx=5, pady=5) self.frame_flag_count.config(background='black') self.counterDigit = Counter(self.frame_flag_count, 35, 5, 10, 3) self.counter10s = Counter(self.frame_flag_count, 20, 5, 10, 3) self.counter100s = Counter(self.frame_flag_count, 5, 5, 10, 3) # FRAME SMILEY self.frame_smiley = tk.Frame(self.frame_over_grid) self.frame_smiley.grid(row=0, column=1, padx=5, pady=5) self.frame_smiley.config(background='#C0C0C0') self.smiley_button = tk.Button( self.frame_smiley, text='smiley', image=self.image_smiley, command=self.call_new_grid_window, ) self.smiley_button.grid(row=0) # FRAME TIME COUNTER self.time = 0 self.timer_status = False self.frame_time_counter = tk.Canvas(self.frame_over_grid, width=45, height=25) self.frame_time_counter.grid(row=0, column=2, sticky=tk.E, padx=5, pady=5) self.frame_time_counter.config(background='black') self.timeDigit = Counter(self.frame_time_counter, 35, 5, 10, 3) self.time10s = Counter(self.frame_time_counter, 20, 5, 10, 3) self.time100s = Counter(self.frame_time_counter, 5, 5, 10, 3) self.timeDigit.reveal_segments(0) self.time10s.reveal_segments(0) self.time100s.reveal_segments(0) # Creates the grid. self.create_hidden_and_button_board(self.length, self.height, self.mines) self.reset_flag_count() # Update clock self.root.after(1000, self.update_clock) self.root.mainloop() def smiley_face_switch(self, won=None, lost=None): """Swaps the smiley and surprised smiley face on mouse click.""" if self.smiley_button['image'] == 'pyimage14': self.smiley_button['image'] = self.image_smiley_surprised elif self.smiley_button['image'] == 'pyimage15': self.smiley_button['image'] = self.image_smiley if won is True: self.smiley_button['image'] = self.image_smiley_won if lost is True: self.smiley_button['image'] = self.image_smiley_lost def load_images(self): """Loads all the images used in the UI.""" # Load images self.image_tile_1 = tk.PhotoImage(file='images/tile_1.png') self.image_tile_2 = tk.PhotoImage(file='images/tile_2.png') self.image_tile_3 = tk.PhotoImage(file='images/tile_3.png') self.image_tile_4 = tk.PhotoImage(file='images/tile_4.png') self.image_tile_5 = tk.PhotoImage(file='images/tile_5.png') self.image_tile_6 = tk.PhotoImage(file='images/tile_6.png') self.image_tile_7 = tk.PhotoImage(file='images/tile_7.png') self.image_tile_8 = tk.PhotoImage(file='images/tile_8.png') self.image_flag = tk.PhotoImage(file='images/flag.png') self.image_mine = tk.PhotoImage(file='images/mine.png') self.image_full_tile = tk.PhotoImage(file='images/full_tile.png') self.image_discovered_tile = tk.PhotoImage( file='images/empty_tile.png') self.image_red_mine = tk.PhotoImage(file='images/red_mine.png') self.image_smiley = tk.PhotoImage(file='images/smiley.png') self.image_smiley_surprised = tk.PhotoImage( file='images/smiley_surprised.png') self.image_smiley_won = tk.PhotoImage(file='images/smiley_won.png') self.image_smiley_lost = tk.PhotoImage(file='images/smiley_lost.png') def call_new_grid_window(self): """Calls the function to create a new grid. It is used here because when using the partial function with self arguments, the smiley face reset would not remember the size of the grid specified by the user because of the nature of partial. """ self.new_grid_window(self.height, self.length, self.mines) def new_grid_window(self, height, length, mines): """Creates a new grid on the main window.""" self.height = height self.length = length self.mines = mines # Kills grid frame self.frame_grid.forget() self.frame_grid.destroy() # Creates new board self.create_hidden_and_button_board(length, height, mines) # Resets Flag Count self.reset_flag_count() def get_settings(self, height, length, mines, window): """Gets the grid settings from the settings window.""" height = height.get() length = length.get() mines = mines.get() if height.isdigit(): height = int(height) else: height = 9 if length.isdigit(): length = int(length) else: length = 9 if mines.isdigit(): if int(mines) < height * length: mines = int(mines) else: mines = int(0.12345 * length * height) else: mines = int(0.12345 * length * height) # Kill pop-up window self.create_board_and_destroy_window(height, length, mines, window) def open_settings_window(self): """Opens the settings window.""" settings_window = tk.Toplevel() settings_window.wm_title('Settings') settings_window_frame = tk.Frame(settings_window) settings_window_frame.grid() height = tk.StringVar() height_label = tk.Label(master=settings_window_frame, text='Height').grid(row=1, column=0) height_entry = tk.Entry(master=settings_window_frame, textvariable=height).grid(row=1, column=1) height.set('9') length = tk.StringVar() length_label = tk.Label(master=settings_window_frame, text='Length').grid(row=2, column=0) length_entry = tk.Entry(master=settings_window_frame, textvariable=length).grid(row=2, column=1) length.set('9') mines = tk.StringVar() mines_label = tk.Label(master=settings_window_frame, text='Number of Mines').grid(row=3, column=0) mines_entry = tk.Entry(master=settings_window_frame, textvariable=mines).grid(row=3, column=1) mines.set('10') beginner_button = tk.Button(master=settings_window_frame, text='Beginner', command=partial(self.set_difficulty, height, length, mines, settings_window, 0)) beginner_button.grid(row=0, column=0) medium_button = tk.Button(master=settings_window_frame, text='Medium', command=partial(self.set_difficulty, height, length, mines, settings_window, 1)) medium_button.grid(row=0, column=1) hard_button = tk.Button(master=settings_window_frame, text='Hard', command=partial(self.set_difficulty, height, length, mines, settings_window, 2)) hard_button.grid(row=0, column=2) create_board_button = tk.Button(master=settings_window_frame, text='Create Board', command=partial( self.get_settings, height, length, mines, settings_window)) create_board_button.grid(row=4, columnspan=3) def spawn_end_game_window(self, won=None, lost=None): """Spawns the window at the end of a game.""" end_game_window = tk.Toplevel() end_game_frame = tk.Frame(end_game_window) end_game_frame.grid() if won is True: text = 'You won!' if lost is True: text = 'You lost.' message = tk.Label(end_game_frame, text=text).grid(row=0) play_again_button = tk.Button( master=end_game_frame, text='Play Again', command=partial(self.create_board_and_destroy_window, self.height, self.length, self.mines, end_game_window)) play_again_button.grid(row=1, column=0) exit_button = tk.Button(master=end_game_frame, text='Exit', command=self.root.destroy) exit_button.grid(row=1, column=1) def update_clock(self): """Updates the clock.""" if self.timer_status is True: self.time += 1 self.timeDigit.reveal_segments(self.time % 10) self.time10s.reveal_segments((self.time // 10) % 10) self.time100s.reveal_segments((self.time // 100) % 10) self.root.after(1000, self.update_clock) def set_difficulty(self, height, length, mines, settings_window, difficulty): """Updates the settings fields on the settings window.""" if difficulty == 0: height.set(9) length.set(9) mines.set(10) elif difficulty == 1: height.set(16) length.set(16) mines.set(40) elif difficulty == 2: height.set(16) length.set(30) mines.set(99) def create_hidden_and_button_board(self, length, height, mines): """It creates a new Minesweeper grid.""" self.list_buttons = [] self.game = Minesweeper() self.game.create_board(length, height, mines) self.game.board.create_random_grid() self.game.board.change_0s_to_blank_spaces() # CREATE GRID FRAME self.frame_grid = tk.Frame(self.frame_whole_window) self.frame_grid.grid(row=1, column=0, padx=5, pady=10) self.frame_grid.config(background='#C0C0C0') # Creates board seen by the user for i, tile in enumerate(self.game.board.tiles): column = i % self.game.board.grid_size[1] row = i // self.game.board.grid_size[1] photo = self.image_full_tile btn = SpecialButton( self.frame_grid, tile=tile, text=str(tile.appearance), rrow=row, ccolumn=column, image=photo, app=self, ) btn.grid(row=row, column=column) self.list_buttons.append(btn) # Reset Smiley self.smiley_button['image'] = self.image_smiley # Reset Timer self.time = 0 self.timer_status = False def reset_flag_count(self): """Resets the flag count to the number of mines on the grid.""" flags_count = self.game.board.flags_count self.counterDigit.reveal_segments(flags_count % 10) self.counter10s.reveal_segments((flags_count // 10) % 10) self.counter100s.reveal_segments((flags_count // 100) % 10) def create_board_and_destroy_window(self, height, length, mines, window): """Destroys the window from which it was called and creates a new grid.""" window.destroy() self.new_grid_window(height, length, mines)
def test_command_mass_reveal_position(self): minesweeper = Minesweeper() minesweeper.new_game() minesweeper.reveal({'row': 0, 'col': 0}) minesweeper.mass_reveal({'row': 0, 'col': 0})