예제 #1
0
    def test_possibility(self):
        desc = None

        try:
            for desc, information_descs, known_mine_spaces, known_clear_spaces, expected_possibilities, expected_probabilities in self.layouts:
                informations = []
                spaces = set()
                for information in information_descs:
                    informations.append(
                        mines.Information(frozenset(information[1:]),
                                          information[0]))
                    spaces.update(information[1:])

                expected_probabilities = dict(expected_probabilities)

                solver = mines.Solver(spaces)

                try:
                    for information in informations:
                        solver.add_information(information)

                    solver.solve()
                except mines.UnsolveableException:
                    self.assertEqual(expected_possibilities, 0, desc)
                else:
                    possibility = solver.get_possibility()

                    for information in information_descs:
                        self.assertEqual(
                            sum(possibility[space]
                                for space in information[1:]), information[0])
        except:
            print("Failing test: %s" % desc)
            raise
예제 #2
0
    def update_board(self, square):
        # Base case: reached a square that was previously uncovered. So, just return.
        if square.isUncovered == True:
            return

        # We are uncovering a square, so if it was in  self.frontier it can no longer be
        if square in self.frontier:
            self.frontier.remove(square)

        # uncover current square
        square.isUncovered = True
        self.numUncovered += 1

        self.solver.add_known_value(square.location, 0)
        self.num_uncovered += 1

        # Recursive case: uncover all neighbors
        if square.value == 0:
            # Get the neighbors if the square.value is 0
            for neighbor in self.get_neighbors(square).values():
                self.update_board(neighbor)
        # We are not going to uncover this square, so we need to update self.frontier by
        # adding all the neighbors of the current square if not already in self.frontier
        else:
            nset = set([])
            for neighbor in self.get_neighbors(square).values():
                # Add neighbors to frontier if not already uncovered and not already in frontier
                if neighbor.isUncovered == False and neighbor not in self.frontier:
                    self.frontier.append(neighbor)
                if neighbor.isUncovered == False:
                    nset.add(neighbor.location)
            info = mines.Information(frozenset(nset), square.value)
            self.solver.add_information(info)
예제 #3
0
    def run_random_test(self, rand):
        num_spaces = rand.randint(1, 15)

        actual_state = [rand.randint(0, 1) for x in range(num_spaces)]

        informations = []

        try:
            solver = mines.Solver(range(num_spaces))

            while len(solver.solved_spaces) != num_spaces:
                solved_spaces = set(solver.solved_spaces)
                unsolved_spaces = set(range(num_spaces)) - solved_spaces

                spaces = choose_n(rand, rand.randint(1, len(unsolved_spaces)), unsolved_spaces) + \
                    choose_n(rand, rand.randint(0, len(solved_spaces)), solved_spaces)

                num_mines = sum(actual_state[i] for i in spaces)

                information = mines.Information(frozenset(spaces), num_mines)

                informations.append(information)

                solver.add_information(information)

                probabilities, num_possibilities = solver.get_probabilities()

                prob_solved_spaces = 0
                for i in range(num_spaces):
                    if i in solver.solved_spaces:
                        prob_solved_spaces += 1
                    elif i in probabilities and probabilities[i] in (
                            0, num_possibilities):
                        prob_solved_spaces += 1

                solver.solve()

                self.assertNotEqual(num_possibilities, 0)

                self.assertEqual(prob_solved_spaces, len(solver.solved_spaces))

                for spaces, total in informations:
                    expected_value = 0
                    for i in spaces:
                        if i in solver.solved_spaces:
                            expected_value += solver.solved_spaces[
                                i] * num_possibilities
                        else:
                            expected_value += probabilities[i]
                    self.assertEqual(expected_value, num_possibilities * total)

            self.assertEqual(
                actual_state,
                [solver.solved_spaces[i] for i in range(num_spaces)])
        except:
            print("State: %s" % actual_state)
            print("Informations: %s" % informations)
            raise
예제 #4
0
    def get_solver(self):
        if self._solver is None:
            solver = mines.Solver(self.spaces)

            if self.mines != -1:
                solver.add_information(
                    mines.Information(self.spaces, self.mines))

            for (space, (value, adjacent)) in self.known_spaces.iteritems():
                solver.add_known_value(space, value)
                if adjacent != -1:
                    solver.add_information(
                        mines.Information(
                            frozenset(self.get_adjacent_spaces(space)),
                            adjacent))

            self._solver = solver

        return self._solver
예제 #5
0
    def __init__(self, row=4, column=4, nbombs=5, verbose=False):
        self.row_size = row
        self.column_size = column

        self.board = []
        self.frontier = []

        self.verbose = verbose

        self.bomb_number = nbombs

        self.bomb_value = -1
        self.covered_value = -2
        self.maked_value = -3
        self.offboard_value = -4

        self.num_uncovered = 0
        self.gameEnd = False

        self.score = 0
        self.gameWon = False

        self.edge_squares = []
        self.corner_squares = []

        self.numUncovered = 0

        spaces = set((x, y) for x in range(self.row_size)
                     for y in range(self.column_size))
        self.solver = mines.Solver(spaces)
        info = mines.Information(frozenset(spaces), self.bomb_number)
        self.solver.add_information(info)

        for row in range(self.row_size):
            self.board.append([])
            for col in range(self.column_size):
                self.board[row].append(Square((row, col)))
                if row == 0 or col == 0 or row == self.row_size - 1 or col == self.column_size - 1:
                    self.edge_squares.append(self.board[row][col])

        for row in [0, self.row_size - 1]:
            for col in [0, self.column_size - 1]:
                #print row, col
                self.edge_squares.remove(self.board[row][col])
                self.corner_squares.append(self.board[row][col])
        #print self.board[3][0] in self.edge_squares
        #print self.corner_squares

        self.insert_mines()

        if verbose:
            print "Playing on %d x %d board with %d bombs" % \
                (self.row_size, self.column_size, nbombs)
예제 #6
0
 def create_solver(self, exclude=None):
     solver = mines.Solver(self.spaces)
     if self.count != -1:
         solver.add_information(mines.Information(self.spaces, self.count))
     for x in range(self.width):
         for y in range(self.height):
             if (x, y) == exclude:
                 continue
             self._add_value_to_solver(solver, x, y,
                                       self.values[x + y * self.width])
     solver.solve()
     return solver
예제 #7
0
    def test_probabilities(self):
        for desc, information_descs, known_mine_spaces, known_clear_spaces, expected_possibilities, expected_probabilities in self.layouts:
            informations = []
            spaces = set()
            for information in information_descs:
                informations.append(
                    mines.Information(frozenset(information[1:]),
                                      information[0]))
                spaces.update(information[1:])

            expected_probabilities = dict(expected_probabilities)

            solver = mines.Solver(spaces)

            try:
                for information in informations:
                    solver.add_information(information)
                probabilities, num_possibilities = solver.get_probabilities()
            except mines.UnsolveableException:
                self.assertEqual(expected_possibilities, 0, desc)
            else:
                self.assertEqual(num_possibilities, expected_possibilities,
                                 desc)

                if expected_possibilities == 0:
                    continue

                for space in spaces:
                    if space in known_mine_spaces:
                        if space in solver.solved_spaces:
                            self.assertEqual(solver.solved_spaces[space], 1,
                                             '%s: %s' % (desc, space))
                            continue
                        expected_probability = num_possibilities
                    elif space in known_clear_spaces:
                        if space in solver.solved_spaces:
                            self.assertEqual(solver.solved_spaces[space], 0,
                                             '%s: %s' % (desc, space))
                            continue
                        expected_probability = 0
                    elif space in expected_probabilities:
                        expected_probability = expected_probabilities[space]
                    else:
                        continue
                    self.assertEqual(probabilities[space],
                                     expected_probability,
                                     '%s: %s' % (desc, space))
예제 #8
0
 def _add_value_to_solver(self, solver, x, y, value):
     if value < 9:
         if solver.solved_spaces.get((x, y), 0) != 0:
             raise mines.UnsolveableException()
         solver.add_known_value((x, y), 0)
         spaces = frozenset(
             self.spaces.intersection((x + i, y + j) for i in range(-1, 2)
                                      for j in range(-1, 2)))
         solver.add_information(mines.Information(spaces, value))
     elif value == MINE:
         if solver.solved_spaces.get((x, y), 1) != 1:
             raise mines.UnsolveableException()
         solver.add_known_value((x, y), 1)
     elif value == CLEAR_Q:
         if solver.solved_spaces.get((x, y), 0) != 0:
             raise mines.UnsolveableException()
         solver.add_known_value((x, y), 0)
예제 #9
0
    def test_solve(self):
        for desc, information_descs, known_mine_spaces, known_clear_spaces, expected_possibilities, expected_probabilities in self.layouts:
            informations = []
            spaces = set()
            for information in information_descs:
                informations.append(
                    mines.Information(frozenset(information[1:]),
                                      information[0]))
                spaces.update(information[1:])

            known_spaces = set(known_mine_spaces)
            known_spaces.update(known_clear_spaces)

            solver = mines.Solver(spaces)

            try:
                for information in informations:
                    solver.add_information(information)

                solver.solve()

                self.assertNotEqual(expected_possibilities, 0, desc)

                self.assertEqual(set(solver.solved_spaces), known_spaces, desc)
                for space in known_mine_spaces:
                    self.assertEqual(solver.solved_spaces[space], 1,
                                     '%s: %s' % (desc, space))
                for space in known_clear_spaces:
                    self.assertEqual(solver.solved_spaces[space], 0,
                                     '%s: %s' % (desc, space))
            except mines.UnsolveableException:
                self.assertEqual(expected_possibilities, 0, desc)
            else:
                probabilities, num_possibilities = solver.get_probabilities()

                self.assertEqual(num_possibilities, expected_possibilities,
                                 desc)

                unknown_spaces = set(spaces)
                unknown_spaces.difference_update(known_spaces)

                self.assertEqual(unknown_spaces, set(probabilities))

                for space, possibilities in expected_probabilities:
                    self.assertEqual(probabilities[space], possibilities,
                                     '%s: %s' % (desc, space))