Ejemplo n.º 1
0
    def test_first_click(self):
        # check with 10 randoms points
        for i in range(100):
            board = Board()  # create new empty board
            board.click(random.randint(0, 6), random.randint(0, 6))

            # game must not be finished because can't click a mine on first turn
            self.assertTrue(board.get_game_status() == GAME_NOT_FINISHED)
Ejemplo n.º 2
0
    def test_check_win(self):
        board = Board()

        # must do first click because mines are only placed after first click
        board.click(0, 0)

        for i in range(board.rows):
            for j in range(board.cols):
                if not board.cells[i][j].has_mine:
                    board.click(i, j)

        self.assertTrue(board.check_win())
        self.assertTrue(board.get_game_status() == GAME_WON)
Ejemplo n.º 3
0
    def test_game_lost_on_mine_click(self):
        board = Board()
        found = False

        # must do first click because mines are only placed after first click
        board.click(0, 0)

        for i in range(board.rows):
            for j in range(board.cols):
                if not found and board.cells[i][j].has_mine:
                    board.click(i, j)
                    found = True

        self.assertFalse(board.check_win())
        self.assertTrue(board.get_game_status() == GAME_LOST)
Ejemplo n.º 4
0
 def __init__(self, driver: WebDriver, game: WebDriver, height, width,
              mines_counter):
     self.game_board = Board(driver, game, height, width, mines_counter)
     self.simple_solver = SimpleSolver(self.game_board)
     self.matrix_solver = MatrixSolver(self.game_board)
Ejemplo n.º 5
0
class LogicSolver(object):
    def __init__(self, driver: WebDriver, game: WebDriver, height, width,
                 mines_counter):
        self.game_board = Board(driver, game, height, width, mines_counter)
        self.simple_solver = SimpleSolver(self.game_board)
        self.matrix_solver = MatrixSolver(self.game_board)

    def play(self):
        self.game_board.send_left_click(floor(self.game_board.height / 2),
                                        floor(self.game_board.width / 2))

        self.game_board.update_fields()

        while self.game_board.game.find_element_by_id('face').get_attribute(
                "class") == 'facesmile':
            if self.game_board.mines_counter == 0:
                self.game_board.click_all_square_blanks()
            else:
                self.game_board.update_fields()
                if self.matrix_solver.matrix_method(self.game_board):
                    self.game_board.update_fields()
                    print('matrix')
                elif self.simple_solver.simple_method(self.game_board):
                    self.game_board.update_fields()
                    print('simple')
                else:
                    blanks = self.game_board.game.find_elements_by_class_name(
                        'square.blank')
                    elems = []
                    for elem in blanks:
                        if elem.get_attribute('style') != 'display: none;':
                            elems.append(elem)
                    if len(elems) > 0:
                        i = int(randrange(len(elems)))
                        elems[i].click()
                        print('guess')

        out = True if self.game_board.game.find_element_by_id(
            'face').get_attribute('class') == 'facewin' else False
        return out
Ejemplo n.º 6
0
 def __init__(self, driver: WebDriver, game: WebDriver, height, width,
              mines_counter):
     self.game_board = Board(driver, game, height, width, mines_counter)
Ejemplo n.º 7
0
class PrologSolver:
    def __init__(self, driver: WebDriver, game: WebDriver, height, width,
                 mines_counter):
        self.game_board = Board(driver, game, height, width, mines_counter)

    def play(self):
        self.game_board.send_left_click(floor(self.game_board.height / 2),
                                        floor(self.game_board.width / 2))

        while True:
            if self.logic_rule_method(self.game_board):
                self.game_board.update_fields()
            else:
                self.game_board.send_left_click(
                    randrange(self.game_board.height),
                    randrange(self.game_board.width))
            if self.game_board.game.find_element_by_id('face').get_attribute(
                    'class') == 'facewin':
                break

        if self.game_board.mines_counter == 0:
            blanks = self.game_board.game.find_elements_by_class_name(
                'square.blank')
            for elem in blanks:
                if elem.get_attribute('style') != 'display: none;':
                    elem.click()

        return self.game_board.update_fields(
        ) and self.game_board.mines_counter == 0

    def logic_rule_method(self, game_board):
        what_to_count = ['square bombflagged', 'square blank']
        for count_option in what_to_count:
            (counting(count_option, A, B)) <= (
                (counting(count_option, A1, B1)) & (A == A1 + 1) &
                (B == B1 + 1) & (squareVector[A] == count_option) & (A <= 8) &
                (B <= 8))
            (counting(count_option, A, B)) <= (
                (counting(count_option, A1, B)) & (A == A1 + 1) &
                (~(squareVector[A] == count_option)) & (A <= 8) & (B <= 8))
            (counting(count_option, A, B)) <= ((A == -1) & (B == 0))
        did_solve_anything = 0
        did_move = 1
        while did_move:
            did_move = 0
            for elem in game_board.neighbours_of_mines:
                print("checking elem (", elem.x, elem.y, ")")
                # rzutowanie kawałka 3x3 z głównej planszy na tablicę prologową
                for i in range(9):
                    if 0 < elem.x + i % 3 <= game_board.width and 0 < elem.y + floor(
                            i / 3) <= game_board.height:
                        +(squareVector[i]
                          == self.game_board.board[elem.y + floor(i / 3) -
                                                   1][elem.x + i % 3 -
                                                      1].game_class)
                    else:
                        +(squareVector[i] == 'BORDER')
                # zapytanie wyrzuca listę tupli
                counted_flagged = pyDatalog.ask(
                    'counting(\'square bombflagged\',8, B)').answers[0][0]
                counted_blank = pyDatalog.ask(
                    'counting(\'square blank\',8, B)').answers[0][0]
                if counted_blank != 0:
                    blank_squares_indexes = pyDatalog.ask(
                        'squareVector[A]==\'square blank\'').answers
                else:
                    blank_squares_indexes = []
                # zaznacz flagi jeśli dookoła pola flagowane i puste sumują się do danej cyfry
                if int(elem.game_class[11],
                       10) == counted_blank + counted_flagged:
                    for blankIndex in blank_squares_indexes:
                        did_solve_anything = 1
                        did_move = 1
                        print("Clicking right at (",
                              elem.x + blankIndex[0] % 3 - 1,
                              elem.y + floor(blankIndex[0] / 3) - 1,
                              ")",
                              end='')
                        self.game_board.send_right_click(
                            elem.y + floor(blankIndex[0] / 3) - 1,
                            elem.x + blankIndex[0] % 3 - 1)
                        print("Clicked")
                # odkryj puste jeśli dookoła jest n oznaczonych flagą
                elif int(elem.game_class[11], 10) == counted_flagged:
                    for blankIndex in blank_squares_indexes:
                        did_solve_anything = 1
                        did_move = 1
                        print("Clicking left at (",
                              elem.x + blankIndex[0] % 3 - 1,
                              elem.y + floor(blankIndex[0] / 3) - 1,
                              ")",
                              end='')
                        self.game_board.send_left_click(
                            elem.y + floor(blankIndex[0] / 3) - 1,
                            elem.x + blankIndex[0] % 3 - 1)
                        print("Clicked")
        return did_solve_anything
Ejemplo n.º 8
0
    def test_illegal_click(self):
        board = Board()

        board.flag_click(0, 0)  # valid
        state1 = json.dumps(board.to_json())

        board.flag_click(100, 100)  # invalid
        state2 = json.dumps(board.to_json())

        board.flag_click(8, 8)  # valid
        state3 = json.dumps(board.to_json())

        self.assertEqual(state1, state2)  # action 2 did not change board
        self.assertNotEqual(state1, state3)  # action 3 changed the board
Ejemplo n.º 9
0
    def test_is_board_empty(self):
        board = Board(8, 8)
        self.assertTrue(board.is_board_empty())

        board.click(random.randint(0, 6), random.randint(0, 6))
        self.assertFalse(board.is_board_empty())
Ejemplo n.º 10
0
    def test_board_not_empty_click(self):
        board = Board()
        board.click(0, 0)

        self.assertFalse(board.is_board_empty())
Ejemplo n.º 11
0
    def test_board_empty_flag_click(self):
        board = Board()
        board.flag_click(0, 0)

        self.assertTrue(board.is_board_empty())
Ejemplo n.º 12
0
 def test_board_init_empty(self):
     board = Board()
     self.assertTrue(board.is_board_empty())
Ejemplo n.º 13
0
 def test_check_not_win_empty_board(self):
     board = Board()
     self.assertFalse(board.check_win())
Ejemplo n.º 14
0
    def test_range_difficulty(self):
        board = Board(9, 9)
        difficulty = board.get_difficulty()

        self.assertGreaterEqual(difficulty, MIN_DIFFICULTY)
        self.assertLessEqual(difficulty, MAX_DIFFICULTY)
Ejemplo n.º 15
0
class MLSolver:
    def __init__(self, driver: WebDriver, game: WebDriver, height, width,
                 mines_counter, model):
        self.game_board = Board(driver, game, height, width, mines_counter)
        self.model = model

    def play(self):
        self.game_board.send_left_click(floor(self.game_board.height / 2),
                                        floor(self.game_board.width / 2))
        self.game_board.update_fields()

        while self.game_board.game.find_element_by_id('face').get_attribute(
                "class") == 'facesmile':
            self.search_outline_fields()

        return True if self.game_board.game.find_element_by_id(
            'face').get_attribute('class') == 'facewin' else False

    def search_outline_fields(self):
        prediction_board = np.zeros(
            [self.game_board.height, self.game_board.width], dtype=float)
        outline_fields = self.game_board.neighbours_of_mines
        mines_coordinates = [list(), list()]

        # for field in outline_fields:
        for i in range(len(outline_fields)):
            prediction_board = self.generate_prediction_board(
                outline_fields[i].y, outline_fields[i].x, prediction_board)

        coord = np.where(prediction_board == np.amax(prediction_board))
        # where zwraca array zw wsp. y i drugi array ze wsp. x
        mines_coordinates[0].extend(coord[0])
        mines_coordinates[1].extend(coord[1])

        # zerowanie wartosci pola, na ktorym wykryto mine
        prediction_board[mines_coordinates[0][0]][mines_coordinates[1][0]] = 0

        # gdyby byly dwa pola o takiej samej wartosci (ew. gdy bez prawdopodobienstw):
        for i in range(len(mines_coordinates[0])):
            if self.game_board.board[mines_coordinates[0][i]][
                    mines_coordinates[1][i]].game_class == 'square blank':
                self.game_board.send_right_click(mines_coordinates[0][i],
                                                 mines_coordinates[1][i])

        for field in outline_fields:
            self.game_board.check_field_neighbours(field.y, field.x)

    def generate_prediction_board(self, y, x, prediction_board):
        matrix_size = 4
        predict_data = []
        coord = []

        for y_shift in range(matrix_size):
            for x_shift in range(matrix_size):
                vector = []
                for j in range(y - y_shift, y + matrix_size - y_shift):
                    if 0 <= j < len(self.game_board.board):
                        for i in range(x - x_shift, x + matrix_size - x_shift):
                            if 0 <= i < len(self.game_board.board[0]):
                                vector.append(
                                    copy.copy(self.game_board.board[j]
                                              [i].mine_neighbours))

                if len(vector) == matrix_size * matrix_size:
                    predict_data.append(vector)
                    coord.append([y - y_shift, x - x_shift])

        # prediction_board = self.predict_mines(predict_data, coord, prediction_board)
        prediction_board = self.predict_mines_probabilities(
            predict_data, coord, prediction_board)

        return prediction_board

    def predict_mines(self, data, coord, prediction_board):
        y_mine, x_mine = self.locate_mines(data)

        for i in range(len(coord)):
            if y_mine[i] != -1:
                prediction_board[y_mine[i] + coord[i][0]][x_mine[i] +
                                                          coord[i][1]] += 1

        return prediction_board

    def locate_mines(self, data):
        labels = self.model.make_prediction(data)

        matrix_size = 4

        x = [label % matrix_size if label != 16 else -1 for label in labels]
        y = [
            int(label / matrix_size) if label != 16 else -1 for label in labels
        ]

        return np.asarray(y), np.asarray(x)

    def predict_mines_probabilities(self, data, coord, prediction_board):
        probabilities = self.model.make_probabilities_prediction(data)

        matrix_size = 4

        for i in range(len(probabilities)):
            for k in range(
                    len(probabilities[0]) -
                    1):  # na ostatniej pozycji prawdopodobienstwo braku miny
                prediction_board[int(k / matrix_size) + coord[i][0]][
                    k % matrix_size + coord[i][1]] += probabilities[i][k]

        return prediction_board