Example #1
0
	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))
Example #2
0
	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()
Example #4
0
 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()
Example #6
0
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
Example #7
0
 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
Example #8
0
    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
Example #9
0
 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))
Example #11
0
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()
    }
Example #12
0
 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:
Example #14
0
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
Example #15
0
@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':
Example #16
0
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
Example #17
0
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
Example #18
0
 def test_query_time_elapsed(self):
     minesweeper = Minesweeper()
     minesweeper.new_game()
     self.assertEqual(minesweeper.time_elapsed(), 0)
Example #19
0
 def test_command_create_a_new_game(self):
     minesweeper = Minesweeper()
     minesweeper.new_game()
Example #20
0
 def test_query_game_status(self):
     minesweeper = Minesweeper()
     minesweeper.new_game()
     self.assertEqual(minesweeper.status(), 'Playing')
Example #21
0
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
Example #22
0
    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')
Example #23
0
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")
Example #25
0
"""Program that allows a user to play Minesweeper on his terminal."""
from Minesweeper import Minesweeper

if __name__ == '__main__':
    GAME = Minesweeper()
    GAME.start()
Example #26
0
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
    }
Example #27
0
from Minesweeper import Minesweeper

game = Minesweeper()

game.playMinesweeper(20, 50)
Example #28
0
 def test_query_mines_remaining(self):
     minesweeper = Minesweeper()
     minesweeper.new_game()
     self.assertEqual(minesweeper.mines_remaining(), 10)
Example #29
0
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)
Example #30
0
 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})