Exemplo n.º 1
0
    def create_minefield(self, form):
        if self.easy_rbtn.isChecked():
            mode = (8, 8, 16)
        elif self.medium_rbtn.isChecked():
            mode = (16, 16, 40)
        elif self.hard_rbtn.isChecked():
            mode = (16, 30, 99)
        elif self.custom_rbtn.isChecked():
            mode = 4
        else:
            mode = 5

        if mode == 5:
            self.msg = QMessageBox()
            self.msg.setIcon(QMessageBox.Information)
            self.msg.setText("Please, select the mode")
            self.msg.setStandardButtons(QMessageBox.Ok)
            self.msg.exec_()
        elif mode == 4:
            pass
        else:
            form.hide()
            self.minefield = Minefield(mode)
            self.minefield.close_btn.clicked.connect(
                lambda: self.destroy_minefield(form))
            self.minefield.show()
Exemplo n.º 2
0
 def __init__(self, processor):
     self.procr = processor
     for s in ['x_size', 'y_size', 'nr_mines', 'diff']:
         setattr(self, s, getattr(self.procr, s))
     # Initialise the game board (all cells unclicked)
     self.board = []
     for j in range(self.y_size):
         self.board.append(self.x_size * ['U'])
     # Instantiate a new minefield
     self.mf = Minefield(self.x_size, self.y_size)
     self.state = Game.READY
     self.start_time = None
Exemplo n.º 3
0
def game():

    m = Minefield.new_game()
    m.welcome()

    actions = {
        ('r', 'reveal'): m.select,
        ('u', 'unflag'): m.unflag,
        ('f', 'flag'): m.flag
    }

    exit_options = ('quit', 'exit', 'q')

    command = None
    while command not in exit_options and not m.game_over:
        print(m)

        location = input("Enter X, Y Coord. >? ")
        x, y = tuple(map(int, location.split(',')))
        coord = y, x

        action = input("Enter action (f)lag (u)nflag or (r)eveal").lower()
        for opts, func in actions.items():
            if action in opts:
                func(coord)
                break
        else:
            print("No such command.")
            continue

        if m.check_win():
            print("You win!")
Exemplo n.º 4
0
 def get_rem_3bv(self):
     """Calculate the minimum remaining number of clicks needed to solve."""
     if self.state == Game.WON:
         return 0
     elif self.state == Game.READY:
         return self.mf.bbbv
     else:
         t = tm.time()
         lost_mf = Minefield(auto_create=False, **self.settings)
         lost_mf.mine_coords = self.mf.mine_coords
         # Replace any openings already found with normal clicks (ones).
         lost_mf.completed_grid = np.where(self.grid < 0,
                                           self.mf.completed_grid, 1)
         # Find the openings which remain.
         lost_mf.get_openings()
         rem_opening_coords = [
             c for opening in lost_mf.openings for c in opening
         ]
         # Count the number of essential clicks that have already been
         # done by counting clicked cells minus the ones at the edge of
         # an undiscovered opening.
         completed_3bv = len({
             c
             for c in where_coords(self.grid >= 0)
             if c not in rem_opening_coords
         })
         return lost_mf.get_3bv() - completed_3bv
Exemplo n.º 5
0
class StartForm(Ui_Form):
    def __init__(self, form):
        self.setupUi(form)
        self.center(form)
        # self.ok_btn.clicked.connect(self.create_minefield)
        self.ok_btn.clicked.connect(lambda: self.create_minefield(form))
        form.show()

    def center(self, form):
        qr = form.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        form.move(qr.topLeft())

    def create_minefield(self, form):
        if self.easy_rbtn.isChecked():
            mode = (8, 8, 16)
        elif self.medium_rbtn.isChecked():
            mode = (16, 16, 40)
        elif self.hard_rbtn.isChecked():
            mode = (16, 30, 99)
        elif self.custom_rbtn.isChecked():
            mode = 4
        else:
            mode = 5

        if mode == 5:
            self.msg = QMessageBox()
            self.msg.setIcon(QMessageBox.Information)
            self.msg.setText("Please, select the mode")
            self.msg.setStandardButtons(QMessageBox.Ok)
            self.msg.exec_()
        elif mode == 4:
            pass
        else:
            form.hide()
            self.minefield = Minefield(mode)
            self.minefield.close_btn.clicked.connect(
                lambda: self.destroy_minefield(form))
            self.minefield.show()

    def destroy_minefield(self, form):
        #self.minefield.setParent(None)
        del self.minefield
        form.show()
Exemplo n.º 6
0
    def reset(self):
        """ Reset the Level """
        self.completionRating = CompletionRating(self)
        self.moveRating = MoveRating(self)
        self.powerRating = PowerRating(self.getPowerRating(), self)

        self.minefield = Minefield(self.rows, self.columns)
        self.drone = Drone(self.minefield, self.moveRating, self.powerRating)

        self.defenseItems = []
        for defenseClass in self.defenses:
            for i in range(self.defenses[defenseClass]):
                self.addDefense(defenseClass)
Exemplo n.º 7
0
def random():
    field = Minefield(*MINEFIELD_PARAM)
    shape = field.get_size()
    return field, shape
Exemplo n.º 8
0
class Game:
    """Store attributes of a game such as the minefield, the start and end time
    etc."""
    READY = 'ready'
    ACTIVE = 'active'
    LOST = 'lost'
    WON = 'won'

    def __init__(self, processor):
        self.procr = processor
        for s in ['x_size', 'y_size', 'nr_mines', 'diff']:
            setattr(self, s, getattr(self.procr, s))
        # Initialise the game board (all cells unclicked)
        self.board = []
        for j in range(self.y_size):
            self.board.append(self.x_size * ['U'])
        # Instantiate a new minefield
        self.mf = Minefield(self.x_size, self.y_size)
        self.state = Game.READY
        self.start_time = None

    def __repr__(self):
        if self.start_time:
            return "<Game object, started at {}>".format(
                tm.strftime('%H:%M, %d %b %Y', tm.localtime(self.start_time)))
        else:
            return "<Game object (not started)>"

    def __str__(self):
        ret = "Game:\n" + str(self.mf)
        if self.start_time:
            time = tm.strftime('%H:%M, %d %b %Y',
                               tm.localtime(self.start_time))
            ret += f"\nStarted at {time}."
        return ret

    def print_board(self):
        replace = {0: '-', 'U': '#'}
        if self.per_cell == 1:
            for char in ['M', 'F', '!', 'X', 'L']:
                replace[char + '1'] = char
        print(prettify_grid(self.board, replace))

    def start_game(self, safe_coords=[]):
        for s in ['first_success', 'drag_select', 'per_cell']:
            setattr(self, s, getattr(self.procr, s))
        self.mf.create(self.nr_mines, self.per_cell, safe_coords)
        self.state = Game.ACTIVE
        self.start_time = tm.time()

    def finalise(self):
        assert self.state in [Game.WON,
                              Game.LOST], "Can't finalise until game is over"
        self.end_time = tm.time()
        self.elapsed = self.end_time - self.start_time

    def get_highscore(self):
        h = {
            'name': self.procr.name,
            'time': round(self.elapsed * 1000),
            '3bv': self.mf.get_3bv(),
            'date': int(self.end_time),
            'flagging': 'F' if bool(self.procr.nr_flags) else 'NF'
        }
        h['key'] = enchs(self, h)
        return h

    #[Check the following methods]
    def get_rem_3bv(self):
        """Calculate the minimum remaining number of clicks needed to solve."""
        if self.state == Game.WON:
            return 0
        elif self.state == Game.READY:
            return self.mf.bbbv
        else:
            t = tm.time()
            lost_mf = Minefield(auto_create=False, **self.settings)
            lost_mf.mine_coords = self.mf.mine_coords
            # Replace any openings already found with normal clicks (ones).
            lost_mf.completed_grid = np.where(self.grid < 0,
                                              self.mf.completed_grid, 1)
            # Find the openings which remain.
            lost_mf.get_openings()
            rem_opening_coords = [
                c for opening in lost_mf.openings for c in opening
            ]
            # Count the number of essential clicks that have already been
            # done by counting clicked cells minus the ones at the edge of
            # an undiscovered opening.
            completed_3bv = len({
                c
                for c in where_coords(self.grid >= 0)
                if c not in rem_opening_coords
            })
            return lost_mf.get_3bv() - completed_3bv

    def get_prop_complete(self):
        """Calculate the progress of solving the board using 3bv."""
        return float(self.mf.bbbv - self.get_rem_3bv()) / self.mf.bbbv

    def get_3bvps(self):
        """Return the 3bv/s."""
        if self.start_time:
            return (self.mf.bbbv * self.get_prop_complete() /
                    self.get_time_passed())
Exemplo n.º 9
0
def play(human=False, show=True, minefield_param=MINEFIELD_PARAM):
    #by default runs as computer version
    #initializes screen if "show" chosen
    if show:
        pygame.init
        pygame.font.init()
        screen = pygame.display.set_mode(SIZE)
        pygame.display.set_caption("Blatant Minesweeper Copy")

        clock = pygame.time.Clock()

    field = Minefield(*minefield_param)
    shape = field.get_size()  # shape of the minefield
    # prepares the rectangles
    if show:
        square_size, square_pos = square_size_position(shape, SIZE)
        rectdict = {}
        rectangles_todraw = []
        for i in range(shape[0]):
            for j in range(shape[1]):
                pos = square_pos + (np.asarray((i, j)) * square_size)
                rectangle = pygame.Rect(pos[0], pos[1],
                                        int(square_size * (1 - SQ_SPACING)),
                                        int(square_size * (1 - SQ_SPACING)))
                rectdict[(i, j)] = rectangle
                rectangles_todraw.append(
                    (screen, BLACK, rectangle, LINE_WIDTH))

    done = False
    lost = False
    won = False
    update = False
    flagged = []  # list of flagged coordinates
    guessed = []  # list of guessed coordinates
    numbers_todraw = []
    mines = field.get_mines()
    squares = shape[0] * shape[1]

    knowledge = np.full(shape, -1)
    '''knowledge is the array that is fed into the AI:
    -1 is not guessed, otherwise the value
    '''

    if show:
        printscreen(screen, flagged, rectangles_todraw, numbers_todraw,
                    rectdict, mines, guessed)
    while not done:
        #when computer, check if user wants to quit
        if show and not human:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    done = True

        #get guess, either for human or computer
        if human:
            guesstype, guesscoord = eventhandler_human(rectdict)
            if guesstype == -1:
                done = True
        else:
            prob_mine = float(mines) / (squares - len(guessed))
            guesstype, guesscoord = eventhandler_ai(knowledge, prob_mine,
                                                    flagged)
            #guesstype, guesscoord = 1, (np.random.randint(0,shape[0]), np.random.randint(0,shape[1]))

        # process left click
        if guesstype == 1:
            if guesscoord in guessed:
                '''
                if not human:
                    lost = True
                    done = True
                    break
                '''
                continue
            toprocess = [guesscoord]
            while True:
                if len(toprocess) != 0:
                    guesscoord = toprocess[0]
                    toprocess.remove(guesscoord)
                if guesscoord in flagged:
                    flagged.remove(guesscoord)

                guessed.append(guesscoord)
                value = field.guess(*guesscoord)
                knowledge[guesscoord] = value
                if value == -1:
                    lost = True
                    done = True
                    if show:
                        rect = rectdict[guesscoord]
                        rectangles_todraw.append((screen, BLACK, rect, 0))
                        update = True
                    break

                elif show:
                    rect = rectdict[guesscoord]
                    number = pygame.font.Font(
                        None,
                        int(square_size * (1 - SQ_SPACING)) - LINE_WIDTH)
                    image = number.render(str(value), True, BLACK)
                    numbers_todraw.append(
                        (image, (rect.center[0] + 1 - image.get_width() / 2,
                                 rect.center[1] + 1 - image.get_height() / 2)))
                    update = True

                if value == 0:
                    for i in range(-1, 2):
                        for j in range(-1, 2):
                            newx = i + guesscoord[0]
                            newy = j + guesscoord[1]
                            if newx < 0 or newy < 0 or newx >= shape[
                                    0] or newy >= shape[1]:
                                continue
                            if (newx, newy) not in guessed and (
                                    newx, newy) not in toprocess:
                                toprocess.append((newx, newy))
                if len(toprocess) == 0:
                    break

        # process right click
        elif guesstype == 3:
            if guesscoord in flagged:
                flagged.remove(guesscoord)
                update = True
            elif guesscoord not in guessed:
                flagged.append(guesscoord)
                update = True

        # updates the screen
        if update and show:
            printscreen(screen, flagged, rectangles_todraw, numbers_todraw,
                        rectdict, mines, guessed)
            update = False

        #checks if won
        if squares - len(guessed) == mines:
            won = True
            done = True

        # ticks
        if human:
            clock.tick(60)
        elif show:
            clock.tick(COMPUTERSPEED)

    #print messages for winning and losing
    if lost and show:
        done = False
        text = pygame.font.Font(None, int(.3 * SIZE[1]))
        image = text.render("You lost!", True, SKY_BLUE)
        screen.blit(image, (SIZE[0] / 2 - image.get_width() / 2,
                            SIZE[1] / 2 - image.get_height() / 2))
        pygame.display.update()
        print("You lost!")

    elif won and show:
        done = False
        text = pygame.font.Font(None, int(.3 * SIZE[1]))
        image = text.render("You won!", True, SKY_BLUE)
        screen.blit(image, (SIZE[0] / 2 - image.get_width() / 2,
                            SIZE[1] / 2 - image.get_height() / 2))
        pygame.display.update()
        print("You won!")

    # if human player, doesn't automatically close the window
    if show:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

    while not done and human:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

    if not human and show:
        time.sleep(1)

    if not human and not lost and not won:
        return -1, False

    # returns the score
    if not human:
        return len(guessed), won