def make_sudoku(self): self.solution = copy.copy(self.field) visited = [[[False for q in range(self.size)] for j in range(self.size)] for i in range(self.count)] self.difficult = self.count * self.count #we will watch every single cage and i - count of visited cage i = 0 while i < self.count**2: area = random.randint(0, 8) row = random.randint(0, 2) colum = random.randint(0, 2) if not (visited[area][row][colum]): visited[area][row][colum] = True i += 1 temp = self.field[area][row][colum] self.field[area][row][colum] = 0 self.difficult -= 1 temp_field = copy.copy(self.field) i_solution = 0 for solution in solver.solve_sudoku((self.size, self.size), self.to_normal_ar()): i_solution += 1 if i_solution != 1: self.field[area][row][colum] = temp self.difficult += 1 self.solution = [ i for i in solver.solve_sudoku((3, 3), self.to_normal_ar()) ][0]
def mix_user_grid(self): flook = [[0] * self.length for i in range(self.length)] iterator = 0 difficult = self.length**2 while iterator < difficult: i, j = random.randrange(0, self.length, 1), random.randrange(0, self.length, 1) if not flook[i][j]: iterator += 1 flook[i][j] = 1 temp = self.user_grid[i][j] self.user_grid[i][j] = 0 difficult -= 1 table_solution = [] for copy_i in range(0, self.length): table_solution.append(self.user_grid[copy_i][:]) i_solution = 0 for solution in solver.solve_sudoku((self.size, self.size), table_solution): i_solution += 1 if i_solution != 1: self.user_grid[i][j] = temp difficult += 1
def create_sudoku(self): """Generate and check sudoku.""" self.origin = self.gen.get_grid_2x( self.gen.mix(self.gen.get_base_grid())) self.grid = copy.deepcopy(self.origin) flook = [[False for j in range(self.gen.size)] for i in range(self.gen.size)] iterator = 0 self.open_cells = self.gen.n**4 while iterator < self.gen.n**4: i = random.randrange(self.gen.size) j = random.randrange(self.gen.size) if not flook[i][j]: flook[i][j] = True iterator += 1 temp = self.grid[i][j] self.grid[i][j] = 0 self.open_cells -= 1 grid_solution = copy.deepcopy(self.grid) solutions = 0 for solution in solve_sudoku((self.gen.n, self.gen.n), grid_solution): solutions += 1 if 1 != solutions: self.grid[i][j] = temp self.open_cells += 1 if ('low' == self.difficult) and (self.__LOW == self.open_cells): break elif ('midle' == self.difficult) and (self.__MIDLE == self.open_cells): break self.board.init_cells(self.grid)
def test_rotate_clockwise(self): lines = board.get_lines("sudoku_boards/hardest.txt") for line in lines: game_board = board.convert_str_to_2d_board(line.replace("\n", "")) generator.rotate_clockwise(game_board) result = solver.solve_sudoku(game_board, False) self.assertEqual(result, True)
def test_switch_numbers(self): lines = board.get_lines("sudoku_boards/hardest.txt") for line in lines: game_board = board.convert_str_to_2d_board(line.replace("\n", "")) for _ in range(10): generator.switch_numbers(game_board, randint(1, 9), randint(1, 9)) result = solver.solve_sudoku(game_board, False) self.assertEqual(result, True)
def test_switch_block_row(self): lines = board.get_lines("sudoku_boards/hardest.txt") for line in lines: game_board = board.convert_str_to_2d_board(line.replace("\n", "")) for _ in range(10): index1 = randint(0, 2) index2 = randint(0, 2) generator.switch_block_row(game_board, index1, index2) result = solver.solve_sudoku(game_board, False) self.assertEqual(result, True)
def remove_clues(size, grid): N = size*size entries = list(product(range(N), range(N))) shuffle(entries) for row,col in entries: entry = grid[row][col] grid[row][col] = 0 solutions = solve_sudoku(size, grid) zero_sols = True try: next(solutions) zero_sols = False next(solutions) grid[row][col] = entry except StopIteration: if zero_sols: grid[row][col] = entry return grid
def generate_full_field(self, amt=10): '''mix_func = ['self.transposing()', 'self.swap_rows_small()', 'self.swap_colums_small()', 'self.swap_rows_area()', 'self.swap_colums_area()'] for _ in xrange(1, amt): id_func = random.randrange(0, len(mix_func), 1) eval(mix_func[id_func])''' flook = [[0 for j in range(self.n * self.n)] for i in range(self.n * self.n)] iterator = 0 difficult = self.n**4 # Первоначально все элементы на месте print("---------------------------") self.show() print("---------------------------") while iterator < self.n**4 and difficult > 78: i, j = random.randrange(0, self.n * self.n, 1), random.randrange( 0, self.n * self.n, 1) # Выбираем случайную ячейку if flook[i][j] == 0: # Если её не смотрели iterator += 1 flook[i][j] = 1 # Посмотрим temp = self.table[i][ j] # Сохраним элемент на случай если без него нет решения или их слишком много self.table[i][j] = 0 difficult -= 1 # Усложняем если убрали элемент table_solution = [] for copy_i in range(0, self.n * self.n): table_solution.append( self.table[copy_i][:]) # Скопируем в отдельный список i_solution = 0 for solution in solver.solve_sudoku((self.n, self.n), table_solution): i_solution += 1 # Считаем количество решений if i_solution != 1: # Если решение не одинственное вернуть всё обратно self.table[i][j] = temp difficult += 1 # Облегчаем self.show() print("difficult = ", difficult)
def main(): image = extract_img() print('Image Extracted') print('\nProcessing Digits...') sudoku = extract_sudoku(image) print('\nSuccessfully Extracted Digits') print("\n\n Sudoku Board") board(sudoku) error_in_board(sudoku) result, possible = solve_sudoku(sudoku) if possible == 1: print(" Solution") board(result) else: print("No solution possible")
def game(): print( "Привет! Введите 'YES', если хочешь продолжить предыдущую игру - иначе что-нибудь другое: " ) ans = input() if ans.upper() == "YES": try: _desk = load() except IOError: _desk = input_desk() else: _desk = input_desk() while not _desk.is_finish(): save(_desk) print(_desk) print("Доступные ячейки для изменения: ") print(*_desk.get_available_cells()) ans = input( "\nВведите номер ряда, колонки и число, которое хотите вcтавить (Например: \"3 2 9\").\nЕсли хочешь посмотреть решение " "- напиши SOLVE:\n") if ans.upper() == "SOLVE": for solution in solve_sudoku((3, 3), _desk.cells): print(*solution, sep='\n') print("В следующий раз получится. Попробуйте еще раз!") return 0 row, column, key = map(int, ans.split()) while not _desk.is_correct_cell( row - 1, column - 1) or not _desk.is_correct_num(key): if not _desk.is_correct_cell(row - 1, column - 1): print("Вы ввели неверный номер ячейки. Попробуйте ещё раз: ") else: print( "Вы ввели неверную цифру для вставки. Попробуйте ещё раз: " ) row, column, key = map(int, input().split()) _desk.change_value(row - 1, column - 1, key) print(_desk) print("Ура, вы победили!")
def test_simple_puzzle(self): puzzle = np.array([[6, 9, 0, 7, 0, 0, 0, 8, 3], [8, 0, 5, 3, 0, 4, 0, 6, 0], [0, 4, 0, 6, 1, 0, 0, 2, 5], [0, 0, 6, 0, 8, 1, 2, 0, 9], [1, 0, 9, 0, 4, 0, 8, 0, 6], [4, 0, 2, 0, 3, 6, 5, 0, 0], [0, 6, 8, 0, 0, 5, 3, 0, 4], [0, 7, 0, 4, 0, 9, 6, 1, 0], [9, 1, 0, 8, 6, 0, 0, 5, 0]]) expected_answer = np.array([[6, 9, 1, 7, 5, 2, 4, 8, 3], [8, 2, 5, 3, 9, 4, 1, 6, 7], [3, 4, 7, 6, 1, 8, 9, 2, 5], [7, 3, 6, 5, 8, 1, 2, 4, 9], [1, 5, 9, 2, 4, 7, 8, 3, 6], [4, 8, 2, 9, 3, 6, 5, 7, 1], [2, 6, 8, 1, 7, 5, 3, 9, 4], [5, 7, 3, 4, 2, 9, 6, 1, 8], [9, 1, 4, 8, 6, 3, 7, 5, 2]]) actual_answer = solver.solve_sudoku(puzzle) self.assertTrue(np.array_equal(expected_answer, actual_answer))
def test_single_backtracking(self): puzzle = np.array([[7, 9, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 6, 9, 0, 0], [8, 0, 0, 0, 3, 0, 0, 7, 6], [0, 0, 0, 0, 0, 5, 0, 0, 2], [0, 0, 5, 4, 1, 8, 7, 0, 0], [4, 0, 0, 7, 0, 0, 0, 0, 0], [6, 1, 0, 0, 9, 0, 0, 0, 8], [0, 0, 2, 3, 0, 0, 0, 0, 0], [0, 0, 9, 0, 0, 0, 0, 5, 4]]) expected_answer = np.array([[7, 9, 6, 8, 5, 4, 3, 2, 1], [2, 4, 3, 1, 7, 6, 9, 8, 5], [8, 5, 1, 2, 3, 9, 4, 7, 6], [1, 3, 7, 9, 6, 5, 8, 4, 2], [9, 2, 5, 4, 1, 8, 7, 6, 3], [4, 6, 8, 7, 2, 3, 5, 1, 9], [6, 1, 4, 5, 9, 7, 2, 3, 8], [5, 8, 2, 3, 4, 1, 6, 9, 7], [3, 7, 9, 6, 8, 2, 1, 5, 4]]) actual_answer = solver.solve_sudoku(puzzle) self.assertTrue(np.array_equal(expected_answer, actual_answer))
def create_sudoku(): """Generate and check sudoku.""" gen = Generator() grid = gen.get_grid_2x(gen.mix(gen.get_base_grid())) flook = [[False for j in range(gen.size)] for i in range(gen.size)] iterator = 0 difficult = gen.n**4 while iterator < gen.n**4: i = random.randrange(gen.size) j = random.randrange(gen.size) if not flook[i][j]: flook[i][j] = True iterator += 1 temp = grid[i][j] grid[i][j] = 0 difficult -= 1 grid_solution = copy.deepcopy(grid) solutions = 0 for solution in solve_sudoku((gen.n, gen.n), grid_solution): solutions += 1 if 1 != solutions: grid[i][j] = temp difficult += 1 return grid, difficult
def buttons(update, context): msg = update._effective_message.text query = update.callback_query # CallbackQueries need to be answered, even if no notification to the user is needed # Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery query.answer() if query.data == '1': game = [[0 for i in range(9)] for j in range(9)] msg = msg.split('\n') for i in range(len(msg)): msg[i] = msg[i].split(' ') q = 0 w = 0 for i in msg: for j in i: try: game[q][w] = int(j) w += (q + 1) // 9 q = (q + 1) % 9 except: ... s = '' for solution in solver.solve_sudoku((3, 3), game): for j in range(len(game)): _ = game[j] if j % 3 == 0: s += '-' * 33 + '\n' for i in range(9): if i % 3 != 0: s += str(_[i]) + ' ' else: s += '| ' + str(_[i]) + ' ' s += '|\n' s += '-' * 33 + '\n' query.edit_message_text(s + "\nРешите, что делать дальше")
def test_hardest_sudoku(self): puzzle = np.array([[8, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 3, 6, 0, 0, 0, 0, 0], [0, 7, 0, 0, 9, 0, 2, 0, 0], [0, 5, 0, 0, 0, 7, 0, 0, 0], [0, 0, 0, 0, 4, 5, 7, 0, 0], [0, 0, 0, 1, 0, 0, 0, 3, 0], [0, 0, 1, 0, 0, 0, 0, 6, 8], [0, 0, 8, 5, 0, 0, 0, 1, 0], [0, 9, 0, 0, 0, 0, 4, 0, 0]]) expected_answer = np.array([[8, 1, 2, 7, 5, 3, 6, 4, 9], [9, 4, 3, 6, 8, 2, 1, 7, 5], [6, 7, 5, 4, 9, 1, 2, 8, 3], [1, 5, 4, 2, 3, 7, 8, 9, 6], [3, 6, 9, 8, 4, 5, 7, 2, 1], [2, 8, 7, 1, 6, 9, 5, 3, 4], [5, 2, 1, 9, 7, 4, 3, 6, 8], [4, 3, 8, 5, 2, 6, 9, 1, 7], [7, 9, 6, 3, 1, 8, 4, 5, 2]]) actual_answer = solver.solve_sudoku(puzzle) self.assertTrue(np.array_equal(expected_answer, actual_answer))
def test_multiple_backtracking(self): puzzle = np.array([[0, 0, 0, 2, 0, 0, 0, 6, 3], [3, 0, 0, 0, 0, 5, 4, 0, 1], [0, 0, 1, 0, 0, 3, 9, 8, 0], [0, 0, 0, 0, 0, 0, 0, 9, 0], [0, 0, 0, 5, 3, 8, 0, 0, 0], [0, 3, 0, 0, 0, 0, 0, 0, 0], [0, 2, 6, 3, 0, 0, 5, 0, 0], [5, 0, 3, 7, 0, 0, 0, 0, 8], [4, 7, 0, 0, 0, 1, 0, 0, 0]]) expected_answer = np.array([[8, 5, 4, 2, 1, 9, 7, 6, 3], [3, 9, 7, 8, 6, 5, 4, 2, 1], [2, 6, 1, 4, 7, 3, 9, 8, 5], [7, 8, 5, 1, 2, 6, 3, 9, 4], [6, 4, 9, 5, 3, 8, 1, 7, 2], [1, 3, 2, 9, 4, 7, 8, 5, 6], [9, 2, 6, 3, 8, 4, 5, 1, 7], [5, 1, 3, 7, 9, 2, 6, 4, 8], [4, 7, 8, 6, 5, 1, 2, 3, 9]]) actual_answer = solver.solve_sudoku(puzzle) self.assertTrue(np.array_equal(expected_answer, actual_answer))
def check(self, lines): for line in lines: game_board = board.convert_str_to_2d_board(line.replace("\n", "")) result = solver.solve_sudoku(game_board, False) print(result) self.assertEqual(result, True)
def run(self): sv.solve_sudoku(self.game_board, True)
flook = [[0 for j in range(example.n*example.n)] for i in range(example.n*example.n)] iterator = 0 difficult = example.n ** 4 #Первоначально все элементы на месте example.show() print "---------------------------" while iterator < example.n ** 4: i,j = random.randrange(0, example.n*example.n ,1), random.randrange(0, example.n*example.n ,1) # Выбираем случайную ячейку if flook[i][j] == 0: #Если её не смотрели iterator += 1 flook[i][j] = 1 #Посмотрим temp = example.table[i][j] #Сохраним элемент на случай если без него нет решения или их слишком много example.table[i][j] = 0 difficult -= 1 #Усложняем если убрали элемент table_solution = [] for copy_i in range(0, example.n*example.n): table_solution.append(example.table[copy_i][:]) #Скопируем в отдельный список i_solution = 0 for solution in solver.solve_sudoku((example.n, example.n), table_solution): i_solution += 1 #Считаем количество решений if i_solution != 1: #Если решение не одинственное вернуть всё обратно example.table[i][j] = temp difficult += 1 # Облегчаем example.show() print "difficult = ",difficult
def test_generator(self): for _ in range(100): game_board = generator.create_permuted_board() result = solver.solve_sudoku(game_board, False) self.assertEqual(result, True)
def test_get_base_grid(self): for _ in range(20): game_board = generator.get_base_grid() result = solver.solve_sudoku(game_board, False) self.assertEqual(result, True)
def gen_rand_grid(size): return remove_clues(size, next(solve_sudoku(size, gen_rand_start_grid(size), shuffle_rows=True)))
im_squares = cv2.cvtColor(crop_img.copy(), cv2.COLOR_GRAY2RGB) for square in squares_int: cv2.rectangle(im_squares, square[0], square[1], (0, 255, 0), 1) cells = ExtractCells.extractCells(crop_img, squares_int) extractedCells = [] for cell in cells: h, w = cell.shape[:2] margin = int(np.mean([h, w]) / 2.5) _, bbox, seed = ExtractCells.LargestConnectedComponent( cell, [margin, margin], [w - margin, h - margin]) extractedCells.append(ExtractCells.extractDigit(cell, bbox, 28)) columns = [] with_border = [ cv2.copyMakeBorder(img.copy(), 1, 1, 1, 1, cv2.BORDER_CONSTANT, None, 255) for img in extractedCells ] for i in range(9): column = np.concatenate(with_border[i * 9:((i + 1) * 9)], axis=0) columns.append(column) Ext_cell = np.concatenate(columns, axis=1) sudoku = ReadSudoKu.readSudoku(model, extractedCells) print("Unsolved sudoku :") PRINT(sudoku) solver.solve_sudoku(sudoku) print("Solved sudoku :") PRINT(sudoku)
def button(update, context): msg = update.message.text keyboard = [[ telegram.KeyboardButton("Сгенерировать судоку"), telegram.KeyboardButton("Решить судоку"), ]] reply_markup = telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=True) # CallbackQueries need to be answered, even if no notification to the user is needed # Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery if msg == "Сгенерировать судоку": game = sudoku_gen.sudoku(3).field s = '' for j in range(len(game)): _ = game[j] if j % 3 == 0: s += '-' * 33 + '\n' for i in range(9): if i % 3 != 0: s += str(_[i]) + ' ' else: s += '| ' + str(_[i]) + ' ' s += '|\n' s += '-' * 33 + '\n' keyboard = [[ telegram.InlineKeyboardButton("Ответ", callback_data='1') ]] reply_markup = telegram.InlineKeyboardMarkup(keyboard) update.message.reply_text(s, reply_markup=reply_markup) elif msg == 'Решить судоку': update.message.reply_text( text= 'Отправляйте головоломку строка за строкой.На месте пропусков ставьте 0.Не ставьте пробелы между цифрами. Вся головоломка должна быть в одном сообщении.' ) elif len(msg) == 89: try: msg = msg.split('\n') for i in range(9): int(msg[i]) try: game = [[0 for i in range(9)] for j in range(9)] for i in range(9): for j in range(9): game[i][j] = int(msg[i][j]) s = '' for solution in solver.solve_sudoku((3, 3), game): for j in range(len(game)): _ = game[j] if j % 3 == 0: s += '-' * 33 + '\n' for i in range(9): if i % 3 != 0: s += str(_[i]) + ' ' else: s += '| ' + str(_[i]) + ' ' s += '|\n' s += '-' * 33 + '\n' update.message.reply_text(text='Решение: \n' + s, reply_markup=reply_markup) except: update.message.reply_text(text='Судоку не имеет решения', reply_markup=reply_markup) except: update.message.reply_text(text='Вы допустили ошибку в вводе', reply_markup=reply_markup)
# Import packages import os import cv2 import sys import imutils from tensorflow.keras.models import load_model # Import solver path = os.getcwd() path = path[:path.rfind('\\') + 1] sys.path.insert(1, path + 'src') from solver import solve_sudoku # Load image image_name = 'test0.jpg' # 'test1.jpg' image = cv2.imread(image_name) image = imutils.resize(image, width=600) # Load recognition model model = load_model(path + r'models\digit_classifier.h5') # Solve sudoku solution = solve_sudoku(image, model) # Save it # cv2.imwrite('result0.jpg', solution) # cv2.imwrite('result1.jpg', solution) # Show it cv2.imshow('Solved puzzle', solution) cv2.waitKey(0)
def print_sudoku(board): print("-"*37) for i, row in enumerate(board): print(("|" + " {} {} {} |"*3).format(*[int(x) if x != 0 else " " for x in row])) if i == 8: print("-"*37) elif i % 3 == 2: print("|" + "---+"*8 + "---|") else: print("|" + " +"*8 + " |") curdir = os.getcwd() sudoku_model_pkl = os.path.join(curdir, 'Computer Vision/sudoku_model.pkl') sudoku_model = pickle.load(open(sudoku_model_pkl, 'rb')) board = detect_board(args['imgpath'], sudoku_model) print('\nBoard detected: ') print_sudoku(board) try: solution = solve_sudoku(board) print('\nSOLUTION: ') print_sudoku(solution) else: prunt('\nDetected board is not a valid sudoku puzzle')
# -*- coding: ascii -*- import solver import display import data_structure as structs table = [ '020800690', '800009007', '009026000', '090410005', '058000710', '300058060', '000360400', '900200008', '043007050' ] data_map = structs.convert_table(table) # Solve the sudoku. while not solver.is_sudoku_solved(data_map): data_map = solver.solve_sudoku(data_map) display.print_sudoku(data_map)
# -*- coding: ascii -*- import solver import display import data_structure as structs table = ['020800690', '800009007', '009026000', '090410005', '058000710', '300058060', '000360400', '900200008', '043007050'] data_map = structs.convert_table(table) # Solve the sudoku. while not solver.is_sudoku_solved(data_map): data_map = solver.solve_sudoku(data_map) display.print_sudoku(data_map)
while True: ret, frame = cap.read() cv2.imshow('Capture',frame) key = cv2.waitKey(1) if key == 27: # Press escape to quit cap.release() break elif key == 32: cap.release() img = frame img = preprocess(img) grid = extract_grid(img) unsolved = deepcopy(grid) solve_sudoku(grid) # Writes the unknown numbers onto the board for i in range(9): for j in range(9): if unsolved[j][i] is 0: cv2.putText(img, str(grid[j][i]), (i*50+15,(j+1)*50-15), 0,1,(0,255,0)) cv2.imshow('Solution',img) key = cv2.waitKey(1) while key is not 27: # Press escape to quit key = cv2.waitKey(1) break cv2.destroyAllWindows()