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 __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)
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:
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))
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!!")
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()
def designMode(self): from Sudoku import Board self.updateBoard(Board([0]*81)) self.mode = Grid.design
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)
from Sudoku import Board sudokuBoard = Board() sudokuBoard.create() sudokuBoard.display()