forked from ndleah/python-mini-project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
180 lines (143 loc) · 4.85 KB
/
main.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
from random import sample
def generate_board(num):
base = 3
side = base * base
def pattern(r, c):
return (base * (r % base) + r // base + c) % side
def shuffle(s):
return sample(s, len(s))
# randomize rows, col, num
rBase = range(base)
rows = [g * base + r for g in shuffle(rBase) for r in shuffle(rBase)]
cols = [g * base + c for g in shuffle(rBase) for c in shuffle(rBase)]
nums = shuffle(range(1, base * base + 1))
# randomized baseline
board_tmp = [[nums[pattern(r, c)] for c in cols] for r in rows]
# print full board
print("=======full board========")
print_board(board_tmp)
# remove numbers of the board
squares = side * side
if num == 0:
# default number of empty slots
empties = squares * 3 // 4
else:
# given number of empty slots
empties = 81 - num
# looping a randomized board for the amount of empty mubers
for p in sample(range(squares), empties):
# set nubers to 0 of the randomized board
board_tmp[p // side][p % side] = 0
# returning the generated board
return board_tmp
"""
This solution works, but it could create boards that are not possible.
def generate_board(num):
bo = [[0 for x in range(9)] for y in range(9)]
for i in range(9):
for j in range(9):
bo[i][j] = 0
for i in range(num):
row = random.randrange(9)
col = random.randrange(9)
num = random.randrange(1, 10)
while not possible(bo, (row, col), num) or bo[row][col] != 0:
row = random.randrange(9)
col = random.randrange(9)
num = random.randrange(1, 10)
bo[row][col] = num
return bo
"""
def print_board(bo):
# looping every line in the array
for i in range(len(bo)):
# printing line if the vertical "box" changes
if i % 3 == 0 and i != 0:
print("- - - - - - - - - - - - - ")
# looping every character in one line
for j in range(len(bo[0])):
# printing lines if the horizontal box changes
# printing each character with spaces except for the last
if j % 3 == 0 and j != 0:
print(" | ", end="")
if j == 8:
# last character is printed without spaces behind
print(bo[i][j])
else:
# printing each character with spaces
print(str(bo[i][j]) + " ", end="")
print("")
def possible(bo, pos, num):
# checking row
for i in range(len(bo[0])):
if bo[pos[0]][i] == num and pos[1] != i:
# not possible
return False
# checking column
for i in range(len(bo)):
if bo[i][pos[1]] == num and pos[0] != i:
# not possible
return False
# checking square
box_x = pos[1] // 3
box_y = pos[0] // 3
for i in range(box_y * 3, box_y * 3 + 3): # row
for j in range(box_x * 3, box_x * 3 + 3): # col
if bo[i][j] == num and (i, j) != pos:
# not possible number
return False
# possible number
return True
def next_empty(bo):
# searching for the next 0 on the board
for i in range(len(bo)):
# looping rows
for j in range(len(bo[0])):
# looping columns
if bo[i][j] == 0:
return i, j # returning row and column
def solve(bo):
# searching for next empty solt
slot = next_empty(bo)
if not slot:
# return True if there is no empty slot
return True
else:
row, col = slot
# looping number 1 to 9
for i in range(1, 10):
# check if the number is possible in this location
if possible(bo, (row, col), i):
# placing the number on the board
bo[row][col] = i
# starting recursion
if solve(bo):
# returns True when the previous returned True
# This will only activate if the board is full
return True
# resetting the changed value to 0
bo[row][col] = 0
return False
# Fill your numbers in the board below or create a new array to solve the board you give.
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]
]
# use this function to generate a new board
# comment and use the array above to solve manual preset boards.
board = generate_board(0)
# printing the unsolved board
print("======solvable board=====")
print_board(board)
# solving the board
solve(board)
# printing the board
print("======solved board=======")
print_board(board)