-
Notifications
You must be signed in to change notification settings - Fork 35
/
210_数独出题.py
123 lines (104 loc) · 3.12 KB
/
210_数独出题.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
import random
import turtle
import copy
import mylib.sudoku as sdk
import time
start = time.time()
def get_full_board(matrix, num_base):
# 初始化棋盘并随机填入若干个满足数独规则的数字(一般小于11个)
for loops in range(num_base):
i, j = random.randint(0, 8), random.randint(0, 8)
choices = sdk.values(matrix, i, j)
if choices:
matrix[i][j] = random.choice(choices)
# 调用求解子程序,获得一个数独终盘
if sdk.sudoku(matrix):
return True
else:
print("生成终盘失败,请重新尝试。")
return False
def dig_holes(tries):
# 挖洞,每欲挖走一个,先测试除了原来数之外的其他数字是否能得到解
for loops in range(tries):
i, j = random.randint(0, 8), random.randint(0, 8)
if board[i][j] == 0:
continue
possible = sdk.values(board, i, j)
unique = True
for num in possible:
temp_board = copy.deepcopy(board)
temp_board[i][j] = num
if sdk.sudoku(temp_board):
unique = False
break
if unique:
answer[i][j] = board[i][j]
board[i][j] = 0
def draw_grid(step=50):
x0, y0 = -step * 4.5, step * 4.5
# 画竖线
for i in range(10):
x = x0 + i * step
tt.penup()
tt.goto(x, y0)
tt.pendown()
tt.pensize(2 if i%3 == 0 else 1)
tt.sety(-y0)
# 画横线
for i in range(10):
y = -y0 + i * step
tt.penup()
tt.goto(x0, y)
tt.pendown()
tt.pensize(2 if i % 3 == 0 else 1)
tt.setx(-x0)
def show_sudoku(matrix, step=50):
x0, y0 = -step * 4 - 5, step * 4 - 15
for i in range(9):
y = y0 - i * step
for j in range(9):
x = x0 + j * step
tt.goto(x, y)
if matrix[i][j] != 0:
tt.write(matrix[i][j], font=('Arial', 24, 'normal'))
def show_answer(x, y):
if x > 220 and y < -220:
show_sudoku(answer)
# ================主程序从这里开始===================
# 第一步,生成终盘
board = [[0 for i in range(9)] for j in range(9)]
answer = [[0 for i in range(9)] for j in range(9)]
while True:
if get_full_board(board, num_base=7):
break
for raw in board:
print(raw)
# 第二步,挖洞并计算难度
dig_holes(99)
level = 0
for raw in range(9):
for col in range(9):
if board[raw][col] == 0:
level += len(sdk.values(board, raw, col))
print("难度系数:", level)
# 记录生成数独盘所花的总时间
end = time.time()
print("花费时间:", end-start)
# 用Turtle画格子,并显示数独盘
turtle.tracer(False)
tt = turtle.Turtle()
draw_grid(step=50)
tt.write(' 难度:' + str(level), font=('Arial', 12, 'normal'))
tt.penup()
show_sudoku(board)
# 画出显示答案的按钮区域
tt.goto(247, -268)
tt.color('FireBrick')
tt.write("点这里\n看答案", font=('Arial', 16, 'normal'))
tt.goto(270, -280)
tt.pendown()
tt.circle(30)
# 接收鼠标事件,显示答案
tt.penup()
turtle.onscreenclick(show_answer)
turtle.done()