def test_hard_sudoku(): global hard_sudoku hard_sudoku = SudokuBoard([[None,3 ,None, 2 ,None,None, None,None,6 ], [None,None,None, None,None,9 , None,None,4 ], [7 ,6 ,None, None,None,None, None,None,None], [None,None,None, None,5 ,None, 7 ,None,None], [None,None,None, None,None,1 , 8 ,6 ,None], [None,5 ,None, 4 ,8 ,None, None,9 ,None], [8 ,None,None, None,None,None, None,None,None], [None,None,None, None,7 ,6 , None,None,None,], [None,7 ,5 , None,None,8 , 1 ,None,None]]) assert hard_sudoku.solved().rows == [[4, 3, 8, 2, 1, 5, 9, 7, 6], [5, 2, 1, 7, 6, 9, 3, 8, 4], [7, 6, 9, 8, 3, 4, 5, 1, 2], [9, 8, 2, 6, 5, 3, 7, 4, 1], [3, 4, 7, 9, 2, 1, 8, 6, 5], [1, 5, 6, 4, 8, 7, 2, 9, 3], [8, 1, 4, 5, 9, 2, 6, 3, 7], [2, 9, 3, 1, 7, 6, 4, 5, 8], [6, 7, 5, 3, 4, 8, 1, 2, 9]] print("Hard sudoku solving test passed")
def test_exceptions(): try: s = SudokuBoard([[],[],[]]) except Exception as e: assert type(e) == InvalidSudokuException try: s = SudokuBoard([[1,2,3,4,5,6,7,8,9],[1,2,3],[],[],[],[],[],[],[]]) except Exception as e: assert type(e) == InvalidSudokuException try: SudokuBoard.subgridize([[],[]]) except Exception as e: assert type(e) == ValueError try: SudokuBoard([[1,1,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None,None]] ) except Exception as e: assert type(e) == InvalidSudokuException print("Passed exceptions test")
def test_solved_sudoku(): solved = SudokuBoard([[7,3,5, 6,1,4, 8,9,2], [8,4,2, 9,7,3, 5,6,1], [9,6,1, 2,8,5, 3,7,4], [2,8,6, 3,4,9, 1,5,7], [4,1,3, 8,5,7, 9,2,6], [5,7,9, 1,2,6, 4,3,8], [1,5,7, 4,9,2, 6,8,3], [6,9,4, 7,3,8, 2,1,5], [3,2,8, 5,6,1, 7,4,9]]) assert solved.is_complete() == True assert solved.is_solved() == True print("Solved sudoku functionality passed")
def test_simple_sudoku(): global s assert SudokuBoard.subgridize([[1,1,1,2,2,2,3,3,3], [1,1,1,2,2,2,3,3,3], [1,1,1,2,2,2,3,3,3]]) == [[1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3, 3, 3]] s = SudokuBoard([[8, 7, 6, 9, None,None, None,None,None], [None,1, None, None,None,6, None,None,None], [None,4, None, 3, None,5, 8, None,None], [4, None,None, None,None,None, 2, 1, None], [None,9, None, 5, None,None, None,None,None], [None,5, None, None,4, None, 3, None, 6], [None,2, 9, None,None,None, None,None,8 ], [None,None,4, 6, 9, None, 1, 7, 3 ], [None,None,None, None,None,1, None,None,4 ]]) assert s.subgrids == [[8, 7, 6, None, 1, None, None, 4, None], [9, None, None, None, None, 6, 3, None, 5], [None, None, None, None, None, None, 8, None, None], [4, None, None, None, 9, None, None, 5, None], [None, None, None, 5, None, None, None, 4, None], [2, 1, None, None, None, None, 3, None, 6], [None, 2, 9, None, None, 4, None, None, None], [None, None, None, 6, 9, None, None, None, 1], [None, None, 8, 1, 7, 3, None, None, 4]] assert s.cols == [[8, None, None, 4, None, None, None, None, None], [7, 1, 4, None, 9, 5, 2, None, None], [6, None, None, None, None, None, 9, 4, None], [9, None, 3, None, 5, None, None, 6, None], [None, None, None, None, None, 4, None, 9, None], [None, 6, 5, None, None, None, None, None, 1], [None, None, 8, 2, None, 3, None, 1, None], [None, None, None, 1, None, None, None, 7, None], [None, None, None, None, None, 6, 8, 3, 4]] assert s.possibilities() == {(0, 4): [1, 2], (0, 5): [2, 4], (0, 6): [4, 5], (0, 7): [2, 3, 4, 5], (0, 8): [1, 2, 5], (1, 0): [2, 3, 5, 9], (1, 2): [2, 3, 5], (1, 3): [2, 4, 7, 8], (1, 4): [2, 7, 8], (1, 6): [4, 5, 7, 9], (1, 7): [2, 3, 4, 5, 9], (1, 8): [2, 5, 7, 9], (2, 0): [2, 9], (2, 2): [2], (2, 4): [1, 2, 7], (2, 7): [2, 6, 9], (2, 8): [1, 2, 7, 9], (3, 1): [3, 6, 8], (3, 2): [3, 7, 8], (3, 3): [7, 8], (3, 4): [3, 6, 7, 8], (3, 5): [3, 7, 8, 9], (3, 8): [5, 7, 9], (4, 0): [1, 2, 3, 6, 7], (4, 2): [1, 2, 3, 7, 8], (4, 4): [1, 2, 3, 6, 7, 8], (4, 5): [2, 3, 7, 8], (4, 6): [4, 7], (4, 7): [4, 8], (4, 8): [7], (5, 0): [1, 2, 7], (5, 2): [1, 2, 7, 8], (5, 3): [1, 2, 7, 8], (5, 5): [2, 7, 8, 9], (5, 7): [8, 9], (6, 0): [1, 3, 5, 6, 7], (6, 3): [4, 7], (6, 4): [3, 5, 7], (6, 5): [3, 4, 7], (6, 6): [5, 6], (6, 7): [5, 6], (7, 0): [5], (7, 1): [8], (7, 5): [2, 8], (8, 0): [3, 5, 6, 7], (8, 1): [3, 6, 8], (8, 2): [3, 5, 7, 8], (8, 3): [2, 7, 8], (8, 4): [2, 3, 5, 7, 8], (8, 6): [5, 6, 9], (8, 7): [2, 5, 6, 9]} assert s.solved().rows == [[8, 7, 6, 9, 1, 4, 5, 3, 2], [3, 1, 5, 2, 8, 6, 7, 4, 9], [9, 4, 2, 3, 7, 5, 8, 6, 1], [4, 3, 8, 7, 6, 9, 2, 1, 5], [6, 9, 1, 5, 2, 3, 4, 8, 7], [2, 5, 7, 1, 4, 8, 3, 9, 6], [1, 2, 9, 4, 3, 7, 6, 5, 8], [5, 8, 4, 6, 9, 2, 1, 7, 3], [7, 6, 3, 8, 5, 1, 9, 2, 4]] assert s.is_complete() == False assert s.is_solved() == False assert s.possible_numbers(1, 0) == [2, 3, 5, 9] assert s.possible_numbers(7, 5) == [2, 8] assert s.possible_numbers(7, 1) == [8] assert s.is_valid() == True print("Basic functionality passed")
def setUp(self): self.board = SudokuBoard(self._input)
def test_get_status(self): solved = SudokuBoard(self._solved) self.assertEquals(self.board.get_status(), (32, 441)) self.assertEquals(solved.get_status(), (81, 0))
class TestSudobuBoard(unittest.TestCase): _input = [ '104 000 306', '809 030 570', '000 070 100', '426 000 003', '087 006 012', '300 000 009', '241 900 030', '000 200 080', '700 503 000' ] _solved = [ '174 895 326', '869 132 574', '532 674 198', '426 719 853', '987 356 412', '315 428 769', '241 987 635', '653 241 987', '798 563 241', ] def setUp(self): self.board = SudokuBoard(self._input) def test_init(self): self.assertEquals(type(self.board.rows[0][2]), type(Square(4))) self.assertEquals(self.board.rows[8][3], Square(5)) def test_repr(self): " only test that it does not throw errors. " repr(self.board) def test_show_options(self): " only test that it does not throw errors. " self.board.show_options() def test_find_options_for(self): "" # TODO def test_identify_only_possibility(self): "" # TODO def test_find_isolation_lines(self): "" # TODO def test_get_cube(self): self.assertEquals(self.board.get_cube(2, 1, self.board.rows), [1, 0, 4, 8, 0, 9, 0, 0, 0]) self.assertEquals(self.board.get_cube(8, 8, self.board.rows), [0, 3, 0, 0, 8, 0, 0, 0, 0]) def test_solved(self): solved = SudokuBoard(self._solved) self.assertTrue(solved.solved()) self.assertFalse(self.board.solved()) def test_get_status(self): solved = SudokuBoard(self._solved) self.assertEquals(self.board.get_status(), (32, 441)) self.assertEquals(solved.get_status(), (81, 0)) def test_all_squares(self): self.assertEquals(len(list(self.board.all_squares())), 81) def test_check_board(self): " check no errors thrown. " self.board.check_board()
def test_solved(self): solved = SudokuBoard(self._solved) self.assertTrue(solved.solved()) self.assertFalse(self.board.solved())
def test_get_status(self): solved = SudokuBoard(self._solved) self.assertEquals(self.board.get_status(), (32,441)) self.assertEquals(solved.get_status(), (81, 0))
class TestSudobuBoard(unittest.TestCase): _input = [ '104 000 306', '809 030 570', '000 070 100', '426 000 003', '087 006 012', '300 000 009', '241 900 030', '000 200 080', '700 503 000' ] _solved = [ '174 895 326', '869 132 574', '532 674 198', '426 719 853', '987 356 412', '315 428 769', '241 987 635', '653 241 987', '798 563 241', ] def setUp(self): self.board = SudokuBoard(self._input) def test_init(self): self.assertEquals(type(self.board.rows[0][2]), type(Square(4))) self.assertEquals(self.board.rows[8][3], Square(5)) def test_repr(self): " only test that it does not throw errors. " repr(self.board) def test_show_options(self): " only test that it does not throw errors. " self.board.show_options() def test_find_options_for(self): "" # TODO def test_identify_only_possibility(self): "" # TODO def test_find_isolation_lines(self): "" # TODO def test_get_cube(self): self.assertEquals(self.board.get_cube(2, 1, self.board.rows), [1,0,4,8,0,9,0,0,0]) self.assertEquals(self.board.get_cube(8,8, self.board.rows), [0,3,0,0,8,0,0,0,0]) def test_solved(self): solved = SudokuBoard(self._solved) self.assertTrue(solved.solved()) self.assertFalse(self.board.solved()) def test_get_status(self): solved = SudokuBoard(self._solved) self.assertEquals(self.board.get_status(), (32,441)) self.assertEquals(solved.get_status(), (81, 0)) def test_all_squares(self): self.assertEquals(len(list(self.board.all_squares())), 81) def test_check_board(self): " check no errors thrown. " self.board.check_board()
class Window(ttk.Frame): def __init__(self, master): super().__init__(master, padding=2) self.create_variables() self.create_widgets() self.create_layout() self.key_binds() self.buttons_bind() def create_variables(self): self.vars = [tk.StringVar() for _ in range(81)] for i in range(81): self.vars[i].set('') self.board = SudokuBoard([['' for _ in range(9)] for _ in range(9)]) def create_widgets(self): self.cells = [ ttk.Entry(self, textvariable=self.vars[i], state='readonly', width=3, font='Calibri 15', justify='center') for i in range(81)] self.generate_button = ttk.Button(self, text='Generate sudoku') self.solve_button = ttk.Button(self, text='Solve sudoku') self.clear_button = ttk.Button(self, text='Clear') self.vsep1 = tk.Frame(self, width=2, bg='black') self.vsep2 = tk.Frame(self, width=2, bg='black') self.hsep1 = tk.Frame(self, height=2, bg='black') self.hsep2 = tk.Frame(self, height=2, bg='black') self.dif_label = ttk.Label(self, text='Difficulty:', justify='center') self.scale = tk.Scale(self, from_=1, to=10, orient='horizontal') self.scale.set(5) def create_layout(self): for i in range(9): for j in range(9): self.cells[i * 9 + j].grid(row=i + i // 3, column=j + j // 3, padx=1, pady=1, sticky=(tk.W, tk.E, tk.S, tk.N)) self.vsep1.grid(row=0, column=3, rowspan=11, sticky=(tk.N, tk.S)) self.vsep2.grid(row=0, column=7, rowspan=11, sticky=(tk.N, tk.S)) self.hsep1.grid(row=3, column=0, columnspan=11, sticky=(tk.E, tk.W)) self.hsep2.grid(row=7, column=0, columnspan=11, sticky=(tk.E, tk.W)) self.generate_button.grid(row=0, column=11, sticky=(tk.W, tk.E, tk.S, tk.N)) self.solve_button.grid(row=1, column=11, sticky=(tk.W, tk.E, tk.S, tk.N)) self.clear_button.grid(row=2, column=11, sticky=(tk.W, tk.E, tk.S, tk.N)) self.dif_label.grid(row=4, column=11, sticky=(tk.W, tk.E, tk.S, tk.N)) self.scale.grid(row=5, column=11, rowspan=2, sticky=(tk.W, tk.E, tk.S, tk.N)) self.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W)) for i in range(11): self.rowconfigure(i, weight=1) self.columnconfigure(i, weight=1) self.columnconfigure(11, weight=1) self.rowconfigure(3, weight=0) self.columnconfigure(3, weight=0) self.rowconfigure(7, weight=0) self.columnconfigure(7, weight=0) self.master.columnconfigure(0, weight=1) self.master.rowconfigure(0, weight=1) def click_1(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 1): self.vars[a].set(1) self.board[a // 9][a % 9] = 1 def click_2(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 2): self.vars[a].set(2) self.board[a // 9][a % 9] = 2 def click_3(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 3): self.vars[a].set(3) self.board[a // 9][a % 9] = 3 def click_4(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 4): self.vars[a].set(4) self.board[a // 9][a % 9] = 4 def click_5(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 5): self.vars[a].set(5) self.board[a // 9][a % 9] = 5 def click_6(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 6): self.vars[a].set(6) self.board[a // 9][a % 9] = 6 def click_7(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 7): self.vars[a].set(7) self.board[a // 9][a % 9] = 7 def click_8(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 8): self.vars[a].set(8) self.board[a // 9][a % 9] = 8 def click_9(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 if self.board.valid(a // 9, a % 9, 9): self.vars[a].set(9) self.board[a // 9][a % 9] = 9 def click_0(self, event): a = str(self.master.focus_get())[15:] if a == '': a = 1 a = int(a) - 1 self.vars[a].set('') def click_solve(self, event): self.board.solved = False for i in range(9): for j in range(9): try: self.board[i][j] = int(self.vars[i * 9 + j].get()) except: self.board[i][j] = '' self.board.solve() for i in range(9): for j in range(9): self.vars[i * 9 + j].set(str(self.board[i][j])) def click_generate(self, event): self.board = generate_sudoku(self.scale.get()) for i in range(9): for j in range(9): self.vars[i * 9 + j].set(str(self.board[i][j])) def click_clear(self, event): for i in range(81): self.vars[i].set('') def buttons_bind(self): self.generate_button.bind('<Button-1>', self.click_generate) self.solve_button.bind('<Button-1>', self.click_solve) self.clear_button.bind('<Button-1>', self.click_clear) def key_binds(self): self.master.bind_all('1', self.click_1) self.master.bind_all('2', self.click_2) self.master.bind_all('3', self.click_3) self.master.bind_all('4', self.click_4) self.master.bind_all('5', self.click_5) self.master.bind_all('6', self.click_6) self.master.bind_all('7', self.click_7) self.master.bind_all('8', self.click_8) self.master.bind_all('9', self.click_9) self.master.bind_all('0', self.click_0) self.master.bind_all('<Return>', self.click_solve) self.master.bind_all('<BackSpace>', self.click_0) self.master.bind_all('<Delete>', self.click_clear)
def create_variables(self): self.vars = [tk.StringVar() for _ in range(81)] for i in range(81): self.vars[i].set('') self.board = SudokuBoard([['' for _ in range(9)] for _ in range(9)])
import boards import sys import logging from solver import solve, SudokuBoard logging.basicConfig(level=logging.WARN) for n, b in boards.__dict__.iteritems(): if not n.startswith('board'): continue print "\n\n%s" % n board = solve(SudokuBoard(b)) print board print "Game won!" if board else "Lost!"
def solve_sudoku(rows): return SudokuBoard(rows).solved().rows