예제 #1
0
    def __init__(self, board=None):
        self.decisions = list()
        self.solved = False

        if board is not None and type(board) is Board:
            self.board = board
        else:
            # Initialize easy board
            self.board = Board()
            self.board.initialize_easy()
예제 #2
0
    def __init__(self, starting_file):

        # opening file
        f = open(starting_file)

        # reducing file to a list of numbers
        numbers = filter(lambda x: x in '123456789', list(reduce(lambda x, y: x + y, f.readlines())))
        numbers = list(map(int, numbers))

        # closing file
        f.close()

        # constructing board
        self.board = Board(numbers)
예제 #3
0
class Generator:

    # constructor for generator, reads in a space delimited
    def __init__(self, starting_file):

        # opening file
        f = open(starting_file)

        # reducing file to a list of numbers
        numbers = filter(lambda x: x in '123456789', list(reduce(lambda x, y: x + y, f.readlines())))
        numbers = list(map(int, numbers))

        # closing file
        f.close()

        # constructing board
        self.board = Board(numbers)

    # function randomizes an existing complete puzzle
    def randomize(self, iterations):

        # not allowing transformations on a partial puzzle
        if len(self.board.get_used_cells()) == 81:

            # looping through iterations
            for x in range(0, iterations):

                # to get a random column/row
                case = random.randint(0, 4)

                # to get a random band/stack
                block = random.randint(0, 2) * 3

                # in order to select which row and column we shuffle an array of
                # indices and take both elements
                options = list(range(0, 3))
                random.shuffle(options)
                piece1, piece2 = options[0], options[1]

                # pick case according to random to do transformation
                if case == 0:
                    self.board.swap_row(block + piece1, block + piece2)
                elif case == 1:
                    self.board.swap_column(block + piece1, block + piece2)
                elif case == 2:
                    self.board.swap_stack(piece1, piece2)
                elif case == 3:
                    self.board.swap_band(piece1, piece2)
        else:
예제 #4
0
    def test_valid_in_row(self):
        board = Board([[3, 0, 6, 5, 0, 8, 4, 0,
                        0], [5, 2, 0, 0, 0, 0, 0, 0, 0],
                       [0, 8, 7, 0, 0, 0, 0, 3,
                        1], [0, 0, 3, 0, 1, 0, 0, 8, 0],
                       [9, 0, 0, 8, 6, 3, 0, 0,
                        5], [0, 5, 0, 0, 9, 0, 6, 0, 0],
                       [1, 3, 0, 0, 0, 0, 2, 5,
                        0], [0, 0, 0, 0, 0, 0, 0, 7, 4],
                       [0, 0, 5, 2, 0, 6, 3, 0, 0]])

        self.assertTrue(valid_in_row(board, 0, 2))
        self.assertFalse(valid_in_row(board, 0, 3))
예제 #5
0
def test():

    board = Board([[0 for j in range(9)] for i in range(9)])
    t1 = time.process_time()
    if generate_complete_sudoku(board):
        t2 = time.process_time()
        print("Generating a complete board took {}\n{}".format((t2 - t1),
                                                               board))
        board = random_reduce_sudoku(board)
        t3 = time.process_time()
        print("Reducing the board took {}\n{}".format((t3 - t2), repr(board)))
    else:
        print("Failed!!")
예제 #6
0
class SudokuSolver:
    """
    Attributes:
        decisions (BoardDecision): list of decisions for guesses made.

    """

    def __init__(self, board=None):
        self.decisions = list()
        self.solved = False

        if board is not None and type(board) is Board:
            self.board = board
        else:
            # Initialize easy board
            self.board = Board()
            self.board.initialize_easy()

    def get_intersecting(self, x, y):
        """
        Return a set of all empty squares that intersect with the selected square

        :param x: row index
        :type x: int
        :param y: column index
        :type y: int
        :return: Set of all empty squares that intersect with selected square
        :rtype: set
        """
        visit_set = set()
        quad_x = x // 3 * 3
        quad_y = y % 3 * 3

        for i in range(0, 9):
            self.add_on_empty(visit_set, x, i)   # col
            self.add_on_empty(visit_set, i, y)   # row
            self.add_on_empty(visit_set, quad_x + i // 3, quad_y + i % 3)    # blk

        return visit_set

    def add_on_empty(self, hash_set, x, y):
        """

        :param hash_set:
        :type hash_set: set
        :param x:
        :type x: int
        :param y:
        :type y: int
        :return:
        :rtype:
        """
        if self.board.is_empty(x, y):
            hash_set.add((x, y))

    def trial_solve(self):
        """
        Attempts to solve the board using trial and error while selecting squares
        that reduce the number of attempts needed. 

        :return:
        :rtype: None
        """
        empty_squares = list()
        for i in range(9):
            for j in range(9):
                if self.board.is_empty(i, j):
                    empty_squares.append((i, j))

        while len(empty_squares) > 0:
            # sort open squares by number of possibilities
            empty_squares.sort(key=lambda l: self.board.getPos(l[0], l[1]).open_count)

            square = empty_squares.pop(0)
            pos = self.board.getPos(square[0], square[1])
            if pos.has_single():
                try:
                    self.board.set_block(square[0], square[1], pos.get_single())
                except AssertionError:
                    # Catch assertions that would make board state invalid
                    self.reset_to_previous()

            else:
                # try guessing
                self.decisions.append(BoardDecision(self.board.__repr__(), square, 0, pos.open_list()))
                try:
                    self.board.set_block(square[0], square[1], pos.open_list()[0])
                except IndexError:
                    self.solved = True
                    return

    def reset_to_previous(self):
        """
        Resets board state to previous decision and tries another path.
        If all paths on that node have been tried move up another node
        and try from that point.

        :return:
        :rtype: None
        """
        length = len(self.decisions)

        # if all paths have been tried return false
        if length is 0:
            self.solved = False
            return
        previous = self.decisions.pop(length-1)
        previous.try_num += 1

        # if we haven't tried all possibilities try the next one
        if previous.try_num < len(previous.open_list):
            self.board.clear_board()
            self.board.set_board(previous.board)
            self.board.set_block(previous.pos[0], previous.pos[1], previous.open_list[previous.try_num])
            self.decisions.append(previous)
            self.trial_solve()
        # tried all possibilities on this node try the previous node
        else:
            self.reset_to_previous()
예제 #7
0
파일: gui.py 프로젝트: amin-gholizad/Sudoku
 def designMode(self):
     from Sudoku import Board
     self.updateBoard(Board([0]*81))
     self.mode = Grid.design
예제 #8
0
파일: gui.py 프로젝트: amin-gholizad/Sudoku
def runGame():
    from Sudoku import Board
    grid = Grid(Board([[1, 0, 0, 0, 0, 0, 5, 0, 0],
                       [0, 0, 0, 8, 0, 0, 0, 0, 0],
                       [0, 0, 9, 0, 0, 0, 0, 6, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 7, 0, 0, 0, 0],
                       [0, 0, 0, 0, 4, 0, 0, 3, 0],
                       [0, 3, 0, 0, 0, 0, 0, 0, 0],
                       [2, 0, 1, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 2, 0, 0, 0, 1, 0]]), w=40, h=40, m=2)

    pygame.init()
    screen = pygame.display.set_mode(grid.get_size())
    pygame.display.set_caption('Soduku')
    clock = pygame.time.Clock()
    fps_max = 60
    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
                break

            if event.type == pygame.MOUSEBUTTONDOWN and event.button == pygame.BUTTON_LEFT:
                pos = pygame.mouse.get_pos()
                grid.selectCell(pos)

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_1 or event.key == pygame.K_KP1:
                    grid.selectedUpdate(1)
                if event.key == pygame.K_2 or event.key == pygame.K_KP2:
                    grid.selectedUpdate(2)
                if event.key == pygame.K_3 or event.key == pygame.K_KP3:
                    grid.selectedUpdate(3)
                if event.key == pygame.K_4 or event.key == pygame.K_KP4:
                    grid.selectedUpdate(4)
                if event.key == pygame.K_5 or event.key == pygame.K_KP5:
                    grid.selectedUpdate(5)
                if event.key == pygame.K_6 or event.key == pygame.K_KP6:
                    grid.selectedUpdate(6)
                if event.key == pygame.K_7 or event.key == pygame.K_KP7:
                    grid.selectedUpdate(7)
                if event.key == pygame.K_8 or event.key == pygame.K_KP8:
                    grid.selectedUpdate(8)
                if event.key == pygame.K_9 or event.key == pygame.K_KP9:
                    grid.selectedUpdate(9)

                if event.key == pygame.K_KP_ENTER or event.key == pygame.K_RETURN:
                    grid.selectedValue()
                if event.key == pygame.K_n and pygame.key.get_mods() and pygame.KMOD_SHIFT:
                    grid.designMode()
                if event.key == pygame.K_s and pygame.key.get_mods() and pygame.KMOD_SHIFT:
                    grid.playMode()
                if event.key == pygame.K_SPACE:
                    grid.playMode()
                    b = grid.board.solve(
                        visual=True, w=grid.cellWidth, h=grid.cellHeight, m=grid.margin)
                    grid.updateBoard(b)

                if event.key == pygame.K_BACKSPACE:
                    grid.selectedUpdate(0)

                if event.key == pygame.K_ESCAPE:
                    done = True
                    break

        grid.draw(screen)
        if grid.mode == Grid.design:
            font = pygame.font.SysFont("comicsansms", 12)
            text = font.render("design mode", True, (0, 128, 0))
            screen.blit(text, (screen.get_width()-text.get_width(),
                               screen.get_height()-text.get_height()))
        pygame.display.flip()
        clock.tick(fps_max)
예제 #9
0
from Sudoku import Board

sudokuBoard = Board()

sudokuBoard.create()

sudokuBoard.display()