diff --git a/android_solver.py b/android_solver.py new file mode 100644 index 0000000..2e32a1e --- /dev/null +++ b/android_solver.py @@ -0,0 +1,182 @@ +# This program allows the sudoku_solver.py script to interact with an android emulator running the app +# 'Sudoku - The Clean One'. + +import pyautogui +import time +import sudoku_solver + +board = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0] +] + +startx, starty = pyautogui.locateCenterOnScreen('./numbers/back.png') +startx = startx - 20 +starty = starty + 73 + +def board_scanner(): + # Scan for Number 1s + pyautogui.click(startx + 60, starty + 512) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x*52), int(starty + y*52), (168, 181, 189), tolerance=10): + board[y][x] = 1 + + # Scan for Number 2s + pyautogui.click(startx + 141, starty + 512) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x*52), int(starty + y*52), (168, 181, 189), tolerance=10): + board[y][x] = 2 + + # Scan for Number 3s + pyautogui.click(startx + 220, starty + 512) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x*52), int(starty + y*52), (168, 181, 189), tolerance=10): + board[y][x] = 3 + + # Scan for Number 4s + pyautogui.click(startx + 301, starty + 512) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x * 52), int(starty + y * 52), (168, 181, 189), tolerance=10): + board[y][x] = 4 + + # Scan for Number 5s + pyautogui.click(startx + 376, starty + 512) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x * 52), int(starty + y * 52), (168, 181, 189), tolerance=10): + board[y][x] = 5 + + # Scan for Number 6s + pyautogui.click(startx + 60, starty + 597) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x * 52), int(starty + y * 52), (168, 181, 189), tolerance=10): + board[y][x] = 6 + + # Scan for Number 7s + pyautogui.click(startx + 141, starty + 597) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x * 52), int(starty + y * 52), (168, 181, 189), tolerance=10): + board[y][x] = 7 + + # Scan for Number 8s + pyautogui.click(startx + 220, starty + 597) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x * 52), int(starty + y * 52), (168, 181, 189), tolerance=10): + board[y][x] = 8 + + # Scan for Number 9s + pyautogui.click(startx + 301, starty + 597) + time.sleep(.25) + for y in range(9): + for x in range(9): + if pyautogui.pixelMatchesColor(int(startx + x * 52), int(starty + y * 52), (168, 181, 189), tolerance=10): + board[y][x] = 9 + + +def fill_in(): + # Place Number 1s + pyautogui.click(startx + 60, starty + 512) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 1: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + # Place Number 2s + pyautogui.click(startx + 141, starty + 512) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 2: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + # Place Number 3s + pyautogui.click(startx + 220, starty + 512) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 3: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + # Place Number 4s + pyautogui.click(startx + 301, starty + 512) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 4: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + # Place Number 5s + pyautogui.click(startx + 376, starty + 512) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 5: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + # Place Number 6s + pyautogui.click(startx + 60, starty + 597) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 6: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + # Place Number 7s + pyautogui.click(startx + 141, starty + 597) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 7: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + # Place Number 8s + pyautogui.click(startx + 220, starty + 597) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 8: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + # Place Number 9s + pyautogui.click(startx + 301, starty + 597) + time.sleep(.25) + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 9: + pyautogui.click(int(startx + x*52), int(starty + y*52)) + + +print('\n\nEmpty Board:') +sudoku_solver.printb(board) +board_scanner() +print('\n\nScanned Board:') +sudoku_solver.printb(board) +sudoku_solver.solve(board) +print('\n\n\nSolved Board:') +sudoku_solver.printb(board) +print('\n\n') +print(board) +fill_in() diff --git a/mousescanner.py b/mousescanner.py new file mode 100644 index 0000000..242e514 --- /dev/null +++ b/mousescanner.py @@ -0,0 +1,8 @@ +import pyautogui +import time + +while True: + print(pyautogui.position()) + x, y = pyautogui.position() + print(pyautogui.pixel(x,y)) + time.sleep(3) \ No newline at end of file diff --git a/numbers/1.png b/numbers/1.png new file mode 100644 index 0000000..c68ff2f Binary files /dev/null and b/numbers/1.png differ diff --git a/numbers/2.png b/numbers/2.png new file mode 100644 index 0000000..f6d17bf Binary files /dev/null and b/numbers/2.png differ diff --git a/numbers/3.png b/numbers/3.png new file mode 100644 index 0000000..9064f09 Binary files /dev/null and b/numbers/3.png differ diff --git a/numbers/4.png b/numbers/4.png new file mode 100644 index 0000000..f5430e2 Binary files /dev/null and b/numbers/4.png differ diff --git a/numbers/5.png b/numbers/5.png new file mode 100644 index 0000000..f47db9b Binary files /dev/null and b/numbers/5.png differ diff --git a/numbers/6.png b/numbers/6.png new file mode 100644 index 0000000..2e47b73 Binary files /dev/null and b/numbers/6.png differ diff --git a/numbers/7.png b/numbers/7.png new file mode 100644 index 0000000..5fbf994 Binary files /dev/null and b/numbers/7.png differ diff --git a/numbers/8.png b/numbers/8.png new file mode 100644 index 0000000..c6cfc42 Binary files /dev/null and b/numbers/8.png differ diff --git a/numbers/9.png b/numbers/9.png new file mode 100644 index 0000000..d14571e Binary files /dev/null and b/numbers/9.png differ diff --git a/numbers/back.png b/numbers/back.png new file mode 100644 index 0000000..c7d19b2 Binary files /dev/null and b/numbers/back.png differ diff --git a/numbers/board.png b/numbers/board.png new file mode 100644 index 0000000..b6710b1 Binary files /dev/null and b/numbers/board.png differ diff --git a/sudoku_solver.py b/sudoku_solver.py new file mode 100644 index 0000000..65ad598 --- /dev/null +++ b/sudoku_solver.py @@ -0,0 +1,72 @@ +# This program solves a sudoku by backtracking and filling all possible spaces. + +def solve(board): + empty = find_empty(board) + + if empty == None: + return True + else: + x, y = empty + + for i in range(1,10): + if check_validity(board, x, y, i): + board[y][x] = i + + if solve(board): + return True + + board[y][x] = 0 + + return False + +# This function Prints a Sudoku Board +def printb(board): + for x in range(len(board)): + if x % 3 == 0: + print('-------------------------') + for y in range(len(board[x])): + if y % 3 == 0: + print('|', end=' ') + print(board[x][y], end=' ') + print('|') + print('-------------------------') + + +# This function checks if a passed number in a set of coordinates in valid. +def check_validity(board, x, y, num): + # Check horizontal + for i in range(len(board)): + if board[y][i] == num and x != i: + return False + + # Check vertical + for i in range(len(board)): + if board[i][x] == num and y != i: + return False + + # Check square + sqr_x = (x // 3) * 3 + sqr_y = (y // 3) * 3 + + for i in range(sqr_y, sqr_y + 3): + for j in range(sqr_x, sqr_x + 3): + if board[i][j] == num and (i, j) != (y, x): + return False + + return True + + +# This function finds the first empty square in the Sudoku. +def find_empty(board): + for y in range(len(board)): + for x in range(len(board)): + if board[y][x] == 0: + return x, y + return None + +# printb(board) +# starttime = time.time() +# solve(board) +# print('\n--------------------------\n') +# printb(board) +# print('\nIt took us ' + str(round(time.time() - starttime)) + ' seconds to solve the sudoku.')