-
Notifications
You must be signed in to change notification settings - Fork 0
/
selen.py
126 lines (105 loc) · 4.15 KB
/
selen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# TODO: Create a function to print the completed board in console.
# TODO: Create a function that tracks the total time the program is running. This stat will differ based on system but would be interesting to see.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
# importing sudoku.py
from sudoku import find_empty_node, solve_Sudoku, check_validity
### PARAMS THAT COULD BECOME PART OF A GUI IN THE FUTURE
# Change this to equal the number of Sudoku boards you want solved.
numberToSolve = 1
# Change to True if you want the browser to close after
closeBrowser = True
# Change to True of you want it to display number of boards solved
printSolved = True
# Change to True if you want Time Elapsed information printed in console.
# timeCount = True
# if timeCount:
# timeStart = time.process_time()
# pass
#pick browser
driver = webdriver.Chrome('chromedriver\chromedriver.exe')
#pick site being used
driver.get("https://sudoku.com/expert/")
#confirm the title has sudoku in it to check for correct page.
assert "sudoku" in driver.title
# not sure if this is necessary tbh
count = 0
while count != numberToSolve:
count = count + 1
time.sleep(2)
#returns an exception if element "game-table" is not located
gameBoard = WebDriverWait(driver,8).until(
EC.presence_of_element_located((By.CLASS_NAME, "game-table"))
)
gameCells = gameBoard.find_elements_by_class_name("game-cell")
#get the initial values of the board given at sudoku.com
i = 0
sudokuTable = [[]]
for x, cell in enumerate(gameCells):
if x % 9 == 0 and x != 0:
sudokuTable.append([])
i = i + 1
value = cell.find_element_by_class_name("cell-value")
try:
text = value.find_element_by_tag_name("svg")
except:
sudokuTable[i].append(0)
continue
width, height = (text.get_attribute("width"), text.get_attribute("height"))
width = int(width)
height = int(height)
# Hacky way to detect the numbers on the board as sudoku.com uses SVGS instead of numbers. This checks
# for height or the special s char at the svg. The dictionary only contains 1-5,7,9 as 6,8 are the same size
# so they use the special s char.
s = text.find_element_by_tag_name("path").get_attribute("d")[0:6]
if s == "M10.53":
sudokuTable[i].append(8)
elif s == "M10.96":
sudokuTable[i].append(6)
else:
dict = {
(12,30) : 1,
(20,31) : 2,
(21,32) : 3,
(24,30) : 4,
(21,31) : 5,
(20,30) : 7,
(23,32) : 9,
}
#This spacing error was really hard to notice haha
sudokuTable[i].append(dict.get((width,height)))
#creating a backup
backup = list(map(list, sudokuTable))
solve_Sudoku(sudokuTable)
### TESTING
# print(backup)
# print(sudokuTable)
#using numpad to input
#numpad chain is numpad > numpad-title
numpad = driver.find_elements_by_class_name("numpad-item")
#game input
for yp, y in enumerate(backup):
for xp, x in enumerate(y):
if x == 0:
gameCells[yp*9 + xp].click()
numpad[sudokuTable[yp][xp] - 1].click()
#sometimes a popup blocks it and causes a crash
if yp == 6:
driver.execute_script("arguments[0].scrollIntoView();", gameBoard)
play_again = WebDriverWait(driver, 10).until(
# not sure why but needed double braces to work
EC.presence_of_element_located((By.CLASS_NAME, "button-play"))
)
## Comment the bottom 2 lines and the while loop above to make it run only once
time.sleep(2)
driver.execute_script("arguments[0].click();", play_again)
if printSolved:
print("This program has solved " + str(numberToSolve) + " Sudoku boards.")
if closeBrowser:
driver.close()
# if timeCount :
# timeFinal = time.process_time() - timeStart
# print("Time elapsed: ", timeFinal - timeStart, "seconds")