Пример #1
0
 def __init__(self):
     self._level = 0
     self._solver = sudoku_solver.SudokuSolver()
     self._max_solver = sudoku_solver.SudokuSolver(randomize_type='max')
     self._min_solver = sudoku_solver.SudokuSolver(randomize_type='min')
     self._sudoku_map = {
         'EASY': [],
         'MEDIUM': [],
         'HARD': [],
         'CHALLENGER': []
     }
Пример #2
0
    def T_test_find_hidden_single(self):
        sparse_empty_0_ = [[[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []]]

        s0 = ss.SudokuSolver()

        empty = [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0]]

        all_possibles = [[[num for num in range(1, 10)] for column in range(9)]
                         for row in range(9)]

        s0.give_initial_digits(empty)
        s0.find_hidden_single()

        cell_array = grids_to_cell_array(empty, all_possibles)
        self.assertEqual(s0.grid, cell_array)

        s0 = ss.SudokuSolver()

        five_ = [[1, 2, 3, 4, 0, 0, 6, 9, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 5, 5, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0]]

        fiveH = [[1, 2, 3, 4, 0, 0, 6, 9, 5], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 5, 5, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0]]

        #cell has right possibles before find_hidden_single
        #house has right possibles

        s0.give_initial_digits(five_)
        s0.find_hidden_single()
        self.assertEqual(s0.grid, fiveH)
Пример #3
0
    def test_update_grid_empty(self):

        # get this to work from setUp
        empty = [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0]]

        all_possibles = [[[num for num in range(1, 10)] for column in range(9)]
                         for row in range(9)]

        s1 = ss.SudokuSolver()
        s1.give_initial_digits(empty)

        empty_cells = grids_to_cell_array(empty, all_possibles)
        print(empty_cells)

        self.assertEqual(s1.grid, empty_cells)

        self.assertTrue(s1.rows[0][0] is s1.columns[0][0])
        self.assertTrue(s1.rows[0][0] is s1.squares[0][0])
        self.assertTrue(s1.rows[1][1] is s1.columns[1][1])

        self.assertTrue(s1.rows[4][4] is s1.squares[4][4])
 def _solved_puzzle_image(self, stringified_puzzle):
     solver = sudoku_solver.SudokuSolver()
     solution = ''
     solution = solver.solve(stringified_puzzle)
     image_solution = self.parser.draw_solution(solution)
     image_solution = self.parser.convert_to_jpeg(image_solution)
     return image_solution
Пример #5
0
def main():

    sudoku = sio.parse_sudoku("mesi.sud")

    solutions = []

    solver = ss.SudokuSolver()
    solver(sudoku, solutions)

    sio.write_solution_to_file(solutions, "mesi-solution.txt")
Пример #6
0
    def test_update_grid_hard(self):
        hard_one = [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 4, 9, 3, 0, 0, 2, 1, 0],
                    [5, 1, 0, 0, 0, 9, 0, 0, 0], [0, 3, 1, 9, 0, 4, 0, 7, 6],
                    [0, 0, 0, 0, 7, 0, 0, 0, 0], [0, 8, 5, 1, 0, 3, 0, 2, 9],
                    [3, 5, 0, 0, 0, 1, 0, 0, 0], [0, 7, 8, 4, 0, 0, 9, 3, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0]]

        s1 = ss.SudokuSolver()

        self.assertTrue(s1.rows[0][0] is s1.columns[0][0])
        self.assertTrue(s1.rows[0][0] is s1.squares[0][0])
        self.assertTrue(s1.rows[1][1] is s1.columns[1][1])

        self.assertTrue(s1.rows[4][4] is s1.squares[4][4])

        s1.give_initial_digits(hard_one)

        hard_one_possibles = [[[2, 6, 7, 8], [2, 6], [2, 3, 6, 7],
                               [2, 5, 6, 7, 8], [1, 2, 4, 5, 6, 8],
                               [2, 5, 6, 7, 8], [3, 4, 5, 6, 7, 8],
                               [4, 5, 6, 8, 9], [3, 4, 5, 7, 8]],
                              [[6, 7, 8], [], [], [], [5, 6, 8], [5, 6, 7, 8],
                               [], [], [5, 7, 8]],
                              [[], [], [2, 3, 6, 7], [2, 6, 7, 8],
                               [2, 4, 6, 8], [], [3, 4, 6, 7, 8], [4, 6, 8],
                               [3, 4, 7, 8]],
                              [[2], [], [], [], [2, 5, 8], [], [5, 8], [], []],
                              [[2, 4, 6, 9], [2, 6, 9], [2, 4, 6],
                               [2, 5, 6, 8], [], [2, 5, 6, 8], [1, 3, 4, 5, 8],
                               [4, 5, 8], [1, 3, 4, 5, 8]],
                              [[4, 6, 7], [], [], [], [6], [], [4], [], []],
                              [[], [], [2, 4, 6], [2, 6, 7, 8], [2, 6, 8, 9],
                               [], [4, 6, 7, 8], [4, 6, 8], [2, 4, 7, 8]],
                              [[1, 2, 6], [], [], [], [2, 5, 6], [2, 5, 6], [],
                               [], [1, 2, 5]],
                              [[1, 2, 4, 6, 9], [2, 6, 9], [2, 4, 6],
                               [2, 5, 6, 7, 8], [2, 3, 5, 6, 8, 9],
                               [2, 5, 6, 7, 8], [1, 4, 5, 6, 7, 8],
                               [4, 5, 6, 8], [1, 2, 4, 5, 7, 8]]]

        # for rowIndex, row in enumerate(s1.grid):
        #     for columnIndex, cell in enumerate(row):
        #         self.assertEqual(cell.possibes, hard_one_possibles[rowIndex][columnIndex])

        hard_one_cells = grids_to_cell_array(hard_one, hard_one_possibles)
        self.assertEqual(s1.grid, hard_one_cells)

        self.assertTrue(s1.rows[0][0] is s1.columns[0][0])
        self.assertTrue(s1.rows[0][0] is s1.squares[0][0])
        self.assertTrue(s1.rows[1][1] is s1.columns[1][1])

        self.assertTrue(s1.rows[4][4] is s1.squares[4][4])
        self.assertTrue(s1.rows[1][2] is s1.columns[2][1])

        self.assertTrue(s1.squares[7][2] is s1.columns[5][6])
Пример #7
0
def test_generator(generator, level):
    sudoku = generator.get_sudoku(level=level)
    passed = True
    actual_level = generator.get_sudoku_level(sudoku)
    if level != actual_level:
        print('Level does not match. Expected {}. Actual {}'.format(
            level, actual_level))
        passed = False
    solver = sudoku_solver.SudokuSolver()
    solution = solver.solve(sudoku)
    if not solution:
        print('Can not solve the generated sudoku.')
        passed = False
    if not passed:
        raise RuntimeError('Test for {} level failed.'.format(level))
Пример #8
0
    def get(self):
        """Simplistic solver API"""

        puzzle = self.request.get('puzzle')
        if puzzle:
            solver = sudoku_solver.SudokuSolver()
            try:
                solution = solver.solve(puzzle)
            except (sudoku_solver.ContradictionError, ValueError) as e:
                logging.debug(e)
                self.response.write(
                        '%s Puzzle: %s.' % (str(e), puzzle))
                return
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.write(solution)
        else:
            self.response.write('No puzzle data')
Пример #9
0
 def __init__(self, stdscr):
     self.stdscr = stdscr
     self.height = 18
     self.width = 36
     self.curr_row = 4
     self.curr_col = 4
     self.curr_color = 1
     self.message = None
     self.confirm = None
     self.mouse_x = None
     self.mouse_y = None
     self.level = 'Easy'
     self.sudoku = sudoku_data.SudokuData()
     self.solver = sudoku_solver.SudokuSolver()
     self.generator = sudoku_generator.SudokuGenerator()
     self._setup_colors()
     self.data_file = '/tmp/magic_sudoku.data'
     self.changes = []
     self.redo_changes = []
Пример #10
0
def test_solver(path, type):
    if type == 'partial':
        partial = True
        simple = False
    elif type == 'simple':
        partial = False
        simple = True
    else:
        partial = False
        simple = False
    for file_name in os.listdir(path):
        full_name = os.path.join(path, file_name)
        sudoku, expected_solution = read_data_file(full_name)
        original = sudoku_data.SudokuData()
        original.copy(sudoku)
        solution = sudoku_solver.SudokuSolver().solve(sudoku,
                                                      partial=partial,
                                                      simple=simple)
        compare_solutions(full_name, solution, expected_solution)
        compare_sudoku(full_name, sudoku, original, solution)
    print('Tests in {!r} with type {!r} passed.'.format(path, type))
Пример #11
0
    def test_find_naked_single(self):
        all_possibles = [[[num for num in range(1, 10)] for column in range(9)]
                         for row in range(9)]

        sparse_empty_0_ = [[[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []]]

        s0 = ss.SudokuSolver()
        s0.possiblesByCell = sparse_empty_0_

        empty = [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0]]

        s0.find_naked_single()
        cell_array = grids_to_cell_array(empty, all_possibles)
        self.assertEqual(s0.grid, cell_array)

        sparse_empty_1_ = [[[5], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []]]

        s1 = ss.SudokuSolver()
        s1.possiblesByCell = sparse_empty_1_

        just5 = [[5, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0]]

        s1.find_naked_single()
        cell_array = grids_to_cell_array(just5, sparse_empty_1_)
        self.assertEqual(s1.grid, cell_array)

        sparse_empty_2_ = [[[], [], [], [], [], [], [3, 6, 7], [], []],
                           [[], [], [7], [], [], [1, 2, 8], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [8], [], []],
                           [[], [3], [], [], [], [4, 7, 8, 9], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [2, 4, 6], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], []],
                           [[], [], [], [], [], [], [], [], [9]]]

        s2 = ss.SudokuSolver()
        s2.possiblesByCell = sparse_empty_2_

        justN = [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 7, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 8, 0, 0],
                 [0, 3, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 9]]

        s2.find_naked_single()

        self.assertEqual(s2.grid, justN)
Пример #12
0
 def solve(self):
    solver = sudoku_solver.SudokuSolver(self.board)
    self.solvedboard = solver.solved
    print(self.solvedboard)
Пример #13
0
def run(input_img):
    # open the image
    #img = cv2.imread(filename)
    #peek("1",img)

    # resize all input images to the same size for convenience
    img = cv2.resize(input_img,(900,900))

    img2 = np.copy(img)

    # convert img to grayscale
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #peek("2",gray)

    # blur the image to smooth out noise, even when they look fine they have noise sometimes
    smooth = cv2.GaussianBlur(gray,(3,3),0)
    #peek("3",smooth)

    # adaptive threshold
    thresh = cv2.adaptiveThreshold(smooth,255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11,2)
    thresh2 = cv2.adaptiveThreshold(smooth,255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11,2)
    #peek("4",thresh)

    # find contour lines - after this somehow the thresh img is changed, which is why we have thresh2
    _image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    #cv2.drawContours(img, contours, -1, (0,255,0), 1)
    #peek("3",img)

    # idx = 0 # The index of the contour that surrounds your object
    # mask = np.zeros_like(gray) # Create mask where white is what we want, black otherwise
    # cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask
    # out = np.zeros_like(gray) # Extract out the object and place into output image
    # # out[mask == 255] = img[mask == 255]
    #
    # # Show the output image
    # cv2.imshow('Output', out)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()



    selected_contours = []
    for cnt in contours:
        if cv2.contourArea(cnt) > 5000 and cv2.contourArea(cnt) < 15000: #trying to isolate actual grids, should work if all images are same size
            x,y,w,h = cv2.boundingRect(cnt)
            selected_contours.append((x,y,w,h))

    #count if there's 81 here
    if len(selected_contours) != 81:
        print("ERROR: wrong number of contours somehow")
        sys.exit()


    #sort contours by x,y, (starting in top left)
    selected_contours = sorted(selected_contours, key=operator.itemgetter(1,0))
    contour_values = []
    puzzle = [[],[],[],[],[],[],[],[],[]]
    row_count = 0
    #cut out and save
    idx =0
    for x,y,w,h in selected_contours:
        #if cv2.contourArea(cnt) > 10000 and cv2.contourArea(cnt) < 20000:#trying to isolate actual grids HOPEFULLY EXACTLY 81
        idx += 1
        #x,y,w,h = cv2.boundingRect(cnt)
        roi=thresh2[y+5:y+h-5,x+5:x+w-5] #used to be img (which is not pure black/white) #also cropping black edges off
        # cv2.imshow('ROI',roi)
        # cv2.waitKey(0)
        # cv2.imwrite("grid_pics/" + str(idx) + '.jpg', roi) #SAVING PICS FOR ANALYSIS
        #print(str(idx) + ":" + image_file_to_string("grid_pics/" + str(idx) + '.jpg'))

        #cv2.rectangle(img,(x,y),(x+w-2,y+h-2),(0,255,0),1)

        #get the number using my FANCY OCR
        #num = henry_ocr.get_number_from_img("grid_pics/" + str(idx) + '.jpg')
        num = henry_ocr.get_number_from_img(roi)
        #print(str(idx) + ":" + num, x, y)#, cv2.contourArea(cnt))

        #save number or blank into next slot of board data structure
        if num:
            puzzle[row_count / 9].append(num)
            cv2.putText(img2,num,(x+w/8,y+h/3),0,1,(255,0,0),2)
        else:
            puzzle[row_count / 9].append("x")
        row_count += 1

        contour_values.append((x,y,w,h,num)) #this is just used for writing solution to img

    #peek("4", img)

    print('\n'.join([''.join(['{:4}'.format(item) for item in row]) for row in puzzle]))

    # cv2.imshow('img',img)
    # cv2.waitKey(0)


    #################TIME TO SOLVE###########################

    #["..9748...","7........",".2.1.9...","..7...24.",".64.1.59.",".98...3..","...8.3.2.","........6","...2759.."]
    #[[],[],[],[],[],[],[],[],[]]


    #probably helpful if this returns True/False on success/failure
    s = sudoku_solver.SudokuSolver()
    s.solveSudoku(puzzle)
    print "Count:" ,s.count
    print "\n*********************\n"
    print('\n'.join([''.join(['{:4}'.format(item) for item in row]) for row in puzzle]))


    #print contour_values

    #PRINT SOLUTION
    #we need to know which boxes were empty (x), and their coordinates so we can write the new value
    i = 0
    for x,y,w,h,num in contour_values:
        if num == "":
            #draw at x,y, using puzzle[i/9][i%9]
            cv2.putText(img,str(puzzle[i/9][i%9]),(x+w/4,y+h * 3/4),0,3,(0,255,0),5)
            #cv2.putText(out,string,(x,y+h),0,1,(0,255,0))
        i += 1

    #cv2.imwrite("static/output2.png", img)
    #cv2.imshow('FINAL',img)
    #cv2.waitKey(0)

    return img2, img
Пример #14
0
import sudoku_parser
import sudoku_solver
from cv2 import imshow, waitKey
from sys import argv

sudoku = sudoku_parser.SudokuParser()
solver = sudoku_solver.SudokuSolver()
if not argv[1]:
    raise IndexError
puzzle = sudoku.parse(argv[1])
solution = solver.solve(puzzle)
sudoku.draw_solution(solution)
imshow('result', sudoku.resized_largest_square)
waitKey(0)