首先是生成数独9*9的框,
,
,
,
,
,
我不会,所以是抄的 改了亿点点
weixin_39982537/article/details/111627821
改完是这样的
import random
import math
matrix = []
sds = []
def get_random_unit():
_num_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(_num_list)
return _num_list
def print_grid(arr):
for i in range(9):
sds.append(arr[i])
def get_row(row):
row_arr = []
for v in matrix[row]:
if v == 0:
continue
row_arr.append(v)
return row_arr
def get_col(col):
col_arr = []
for i in range(9):
val = matrix[i][col]
if val == 0:
continue
col_arr.append(matrix[i][col])
return col_arr
def get_block(num):
col_arr = []
seq = num % 3
col_end = 9 if seq == 0 else seq * 3
row_end = int(math.ceil(num / 3) * 3)
for i in range(row_end - 3, row_end):
for j in range(col_end - 3, col_end):
val = matrix[i][j]
if val != 0:
col_arr.append(matrix[i][j])
return col_arr
def get_block_seq(row, col):
col_seq = int(math.ceil((col + 0.1) / 3))
row_seq = int(math.ceil((row + 0.1) / 3))
return 3 * (row_seq - 1) + col_seq
def get_enable_arr(row, col):
avail_arr = get_random_unit()
seq = get_block_seq(row, col)
block = get_block(seq)
row = get_row(row)
col = get_col(col)
unable_arr = list(set(block + row + col))
for v in unable_arr:
if v in avail_arr:
avail_arr.remove(v)
return avail_arr
def main():
can_num = {}
count = 0
for i in range(9):
matrix.append([0] * 9)
num_list = get_random_unit()
for row in range(3):
for col in range(3):
matrix[row][col] = num_list.pop(0)
num_list = get_random_unit()
for row in range(3, 6):
for col in range(3, 6):
matrix[row][col] = num_list.pop(0)
num_list = get_random_unit()
for row in range(6, 9):
for col in range(6, 9):
matrix[row][col] = num_list.pop(0)
box_list = []
for row in range(9):
for col in range(9):
if matrix[row][col] == 0:
box_list.append({'row': row, 'col': col})
i = 0
while i < len(box_list):
count += 1
position = box_list[i]
row = position['row']
col = position['col']
key = '%dx%d' % (row, col)
if key in can_num:
enable_arr = can_num[key]
else:
enable_arr = get_enable_arr(row, col)
can_num[key] = enable_arr
if len(enable_arr) <= 0:
i -= 1
if key in can_num:
del (can_num[key])
matrix[row][col] = 0
continue
else:
matrix[row][col] = enable_arr.pop()
i += 1
print_grid(matrix)
if __name__ == "__main__":
main()
改了第二个函数print_grid sds列表是我自己加的 存储了9个列表,每个元素有9个数字,总共81个符合数独规律的数字
效果如下
每次都会自己随机生成,不需要存储题目,也不用担心用完
然后是
# --------------------华丽の分割线--------------------
ac_num = 0
pausE = True
difficulty = 3
from tkinter import *
from tkinter import ttk
import time
import pygame as py
def setDiff(difF):
global difficulty
global diff
try:
difficulty = int(difF)
diff.destroy()
except:
pass
diff = Tk()
diff.title('难度选择')
diff.geometry('300x90')
diff.resizable(0,0)
Label(diff,text='选择你要挑战的难度!(0~9)',font=('微软雅黑',9)).pack()
cmb = ttk.Combobox(diff)
cmb.pack()
cmb['value'] = (0,1,2,3,4,5,6,7,8,9)
Button(diff,text='我选好了',command=lambda:setDiff(cmb.get())).pack()
diff.mainloop()
一个选择难度的小窗口,pygame用来“多线程”播放背景音乐(我也不知道这叫啥反正用playsound耽误tkinter的主循环)
window = Tk()
window.title('数独')
window.geometry('390x500')
window.resizable(0,0)
begin_time = 0
steps = 0
rights = 0
wrongs = 0
dwc = difficulty*9
ac_name = None
list = range(1,82)
try:
ran = random.sample(list,dwc)
except:
if difficulty > 9:
ran = random.sample(list,9)
elif difficulty < 0:
ran = random.sample(list,1)
print('难度输入出现问题 你将无法通关')
try:
py.mixer.init()
py.mixer.music.load('bg.mp3')
py.mixer.music.play(-1)
except:
print('未检测到名为 bg.mp3 的背景音乐')
def setBlock(num,name):
global begin_time
if begin_time == 0:
begin_time = time.time()
global ac_name
global ac_num
if ac_name != name and name != None and ac_name != None:
ac_name.config(text='?',bg='orange',activebackground='orange',relief='groove')
if name.cget('bg') != 'green':
name.config(text='···',relief='sunken',bg='lightblue',activebackground='lightblue')
ac_name = name
ac_num = num
else:
ac_name = None
def setNum(num):
global ac_name
global begin_time
global dwc
global ac_num
global re
global difficulty
global steps
global wrongs
global rights
global steP
try:
b_color = ac_name.cget('bg')
if ac_num == num:
ac_name.config(text='√',activebackground='green',relief='groove',bg='green')
else:
ac_name.config(text='×',activebackground='red',relief='groove')
ac_name.flash()
ac_name.flash()
if ac_num == num:
ac_name.config(text=str(num),activebackground='green',background='green',relief='groove')
else:
ac_name.config(text='?',bg='orange',activebackground='orange',relief='groove')
if ac_name.cget('bg') == 'green' and b_color == 'lightblue':
dwc -= 1
ac_name = None
rights += 1
steps += 1
elif b_color == 'lightblue' and ac_name.cget('bg') == 'orange':
ac_name = None
wrongs += 1
steps += 1
if dwc == 0:
ac_name = None
print('恭喜,你赢了!')
Label(window,text='恭喜,你赢了!',font=('微软雅黑',30),bg='lightgreen').place(x=52,y=50)
use_time = round(time.time()-begin_time,1)
Label(window,text='用时'+str(use_time)+'秒 正确率'+str(round((rights/steps)*100,1))+'%',bg='yellow').place(x=113,y=121)
re.config(text='剩余数字数量:'+str(dwc)+' 难度等级:'+str(difficulty))
steP.config(text='步数:'+str(steps)+' 正确:'+str(rights)+' 错误:'+str(wrongs))
ac_name = None
except:
pass
def tipSs():
'''global sds
for ynfo in sds:
print(ynfo)'''
global ac_num
global ac_name
try:
ac_name.config(text=str(ac_num))
ac_name.flash()
ac_name.config(text='···')
except:
pass
def pauseOr(bgm):
global pausE
if pausE == True:
py.mixer.music.pause()
Button(window,text='♪',font=('楷体',7),relief='sunken',bg='white',command=lambda:pauseOr(bgm)).place(x=365,y=11)
pausE = False
elif pausE == False:
py.mixer.music.unpause()
Button(window,text='♫',font=('楷体',7),relief='sunken',bg='green',command=lambda:pauseOr(bgm)).place(x=365,y=11)
pausE = True
j=0
i=0.7
_count = 1
wz = False
# 这里通过win10计算器,两年前的项目写出了算法
def spaceBtn(i,j,ri,rj):
name = 'a'+str(i+1)+str(j+1)
name = Button(window,text='?',font=('微软雅黑',10),relief='groove',bg='orange',activebackground='orange',command=lambda:setBlock(sds[i][j],name))
name.place(x=rj*36,y=ri*38,width=30,height=30)
def numBtn(num):
Button(window,text=str(num),font=('楷体',15),relief='sunken',bg='white',activebackground='blue',command=lambda:setNum(num)).place(x=x*42+9,y=380,width=37,height=37)
for info in sds:
for jnfo in info:
j+=1
for znfo in ran:
if _count == znfo:
wz = True
_count += 1
if wz == True:
spaceBtn(round(i-1),j-1,i,j)
wz = False
else:
Label(window,text=jnfo,font=('微软雅黑',10),relief='ridge',bg='grey').place(x=j*36,y=i*38,width=30,height=30)
j=0
i+=1
for x in range(0,9):
numBtn(x+1)
Button(window,text='提示',command=tipSs).place(x=50,y=430)
bgm = Button(window,text='♫',font=('楷体',7),relief='sunken',bg='green',command=lambda:pauseOr(bgm)).place(x=365,y=11)
re = Label(window,text='剩余数字数量:'+str(dwc)+' 难度等级:'+str(difficulty),relief='sunken')
re.place(x=185,y=470)
steP = Label(window,text='步数:'+str(steps)+' 正确:'+str(rights)+' 错误:'+str(wrongs),relief='sunken')
steP.place(x=5,y=470)
window.mainloop()
然后是游戏窗口(真的崩溃了分析不动了自己读吧)
参见小破站:程序员如何才能写出不可维护的代码
用遍历加载的81个框,通过网上搜的方法随机扣的空,并在成功后提醒你,显示通关时间和正确率,就像这样(懒得打一局直接开挂)
放一使用视频感受下
使用视频
最后是完整代码
# csdn上抄的作业:https://blog.csdn.net/weixin_39982537/article/details/111627821 改了亿点点
# 数独4.0:更改掏空数独表格的方式,从原来的每行固定掏n个变为9*9里随机掏9n个
import random
import math
matrix = []
sds = []
def get_random_unit():
_num_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(_num_list)
return _num_list
def print_grid(arr):
for i in range(9):
sds.append(arr[i])
def get_row(row):
row_arr = []
for v in matrix[row]:
if v == 0:
continue
row_arr.append(v)
return row_arr
def get_col(col):
col_arr = []
for i in range(9):
val = matrix[i][col]
if val == 0:
continue
col_arr.append(matrix[i][col])
return col_arr
def get_block(num):
col_arr = []
seq = num % 3
col_end = 9 if seq == 0 else seq * 3
row_end = int(math.ceil(num / 3) * 3)
for i in range(row_end - 3, row_end):
for j in range(col_end - 3, col_end):
val = matrix[i][j]
if val != 0:
col_arr.append(matrix[i][j])
return col_arr
def get_block_seq(row, col):
col_seq = int(math.ceil((col + 0.1) / 3))
row_seq = int(math.ceil((row + 0.1) / 3))
return 3 * (row_seq - 1) + col_seq
def get_enable_arr(row, col):
avail_arr = get_random_unit()
seq = get_block_seq(row, col)
block = get_block(seq)
row = get_row(row)
col = get_col(col)
unable_arr = list(set(block + row + col))
for v in unable_arr:
if v in avail_arr:
avail_arr.remove(v)
return avail_arr
def main():
can_num = {}
count = 0
for i in range(9):
matrix.append([0] * 9)
num_list = get_random_unit()
for row in range(3):
for col in range(3):
matrix[row][col] = num_list.pop(0)
num_list = get_random_unit()
for row in range(3, 6):
for col in range(3, 6):
matrix[row][col] = num_list.pop(0)
num_list = get_random_unit()
for row in range(6, 9):
for col in range(6, 9):
matrix[row][col] = num_list.pop(0)
box_list = []
for row in range(9):
for col in range(9):
if matrix[row][col] == 0:
box_list.append({'row': row, 'col': col})
i = 0
while i < len(box_list):
count += 1
position = box_list[i]
row = position['row']
col = position['col']
key = '%dx%d' % (row, col)
if key in can_num:
enable_arr = can_num[key]
else:
enable_arr = get_enable_arr(row, col)
can_num[key] = enable_arr
if len(enable_arr) <= 0:
i -= 1
if key in can_num:
del (can_num[key])
matrix[row][col] = 0
continue
else:
matrix[row][col] = enable_arr.pop()
i += 1
print_grid(matrix)
if __name__ == "__main__":
main()
# --------------------华丽の分割线--------------------
ac_num = 0
pausE = True
difficulty = 3
from tkinter import *
from tkinter import ttk
import time
import pygame as py
def setDiff(difF):
global difficulty
global diff
try:
difficulty = int(difF)
diff.destroy()
except:
pass
diff = Tk()
diff.title('难度选择')
diff.geometry('300x90')
diff.resizable(0,0)
Label(diff,text='选择你要挑战的难度!(0~9)',font=('微软雅黑',9)).pack()
cmb = ttk.Combobox(diff)
cmb.pack()
cmb['value'] = (0,1,2,3,4,5,6,7,8,9)
Button(diff,text='我选好了',command=lambda:setDiff(cmb.get())).pack()
diff.mainloop()
window = Tk()
window.title('数独')
window.geometry('390x500')
window.resizable(0,0)
begin_time = 0
steps = 0
rights = 0
wrongs = 0
dwc = difficulty*9
ac_name = None
list = range(1,82)
try:
ran = random.sample(list,dwc)
except:
if difficulty > 9:
ran = random.sample(list,9)
elif difficulty < 0:
ran = random.sample(list,1)
print('难度输入出现问题 你将无法通关')
try:
py.mixer.init()
py.mixer.music.load('bg.mp3')
py.mixer.music.play(-1)
except:
print('未检测到名为 bg.mp3 的背景音乐')
def setBlock(num,name):
global begin_time
if begin_time == 0:
begin_time = time.time()
global ac_name
global ac_num
if ac_name != name and name != None and ac_name != None:
ac_name.config(text='?',bg='orange',activebackground='orange',relief='groove')
if name.cget('bg') != 'green':
name.config(text='···',relief='sunken',bg='lightblue',activebackground='lightblue')
ac_name = name
ac_num = num
else:
ac_name = None
def setNum(num):
global ac_name
global begin_time
global dwc
global ac_num
global re
global difficulty
global steps
global wrongs
global rights
global steP
try:
b_color = ac_name.cget('bg')
if ac_num == num:
ac_name.config(text='√',activebackground='green',relief='groove',bg='green')
else:
ac_name.config(text='×',activebackground='red',relief='groove')
ac_name.flash()
ac_name.flash()
if ac_num == num:
ac_name.config(text=str(num),activebackground='green',background='green',relief='groove')
else:
ac_name.config(text='?',bg='orange',activebackground='orange',relief='groove')
if ac_name.cget('bg') == 'green' and b_color == 'lightblue':
dwc -= 1
ac_name = None
rights += 1
steps += 1
elif b_color == 'lightblue' and ac_name.cget('bg') == 'orange':
ac_name = None
wrongs += 1
steps += 1
if dwc == 0:
ac_name = None
print('恭喜,你赢了!')
Label(window,text='恭喜,你赢了!',font=('微软雅黑',30),bg='lightgreen').place(x=52,y=50)
use_time = round(time.time()-begin_time,1)
Label(window,text='用时'+str(use_time)+'秒 正确率'+str(round((rights/steps)*100,1))+'%',bg='yellow').place(x=113,y=121)
re.config(text='剩余数字数量:'+str(dwc)+' 难度等级:'+str(difficulty))
steP.config(text='步数:'+str(steps)+' 正确:'+str(rights)+' 错误:'+str(wrongs))
ac_name = None
except:
pass
def tipSs():
'''global sds
for ynfo in sds:
print(ynfo)'''
global ac_num
global ac_name
try:
ac_name.config(text=str(ac_num))
ac_name.flash()
ac_name.config(text='···')
except:
pass
def pauseOr(bgm):
global pausE
if pausE == True:
py.mixer.music.pause()
Button(window,text='♪',font=('楷体',7),relief='sunken',bg='white',command=lambda:pauseOr(bgm)).place(x=365,y=11)
pausE = False
elif pausE == False:
py.mixer.music.unpause()
Button(window,text='♫',font=('楷体',7),relief='sunken',bg='green',command=lambda:pauseOr(bgm)).place(x=365,y=11)
pausE = True
j=0
i=0.7
_count = 1
wz = False
# 这里通过win10计算器,两年前的项目写出了算法
def spaceBtn(i,j,ri,rj):
name = 'a'+str(i+1)+str(j+1)
name = Button(window,text='?',font=('微软雅黑',10),relief='groove',bg='orange',activebackground='orange',command=lambda:setBlock(sds[i][j],name))
name.place(x=rj*36,y=ri*38,width=30,height=30)
def numBtn(num):
Button(window,text=str(num),font=('楷体',15),relief='sunken',bg='white',activebackground='blue',command=lambda:setNum(num)).place(x=x*42+9,y=380,width=37,height=37)
for info in sds:
for jnfo in info:
j+=1
for znfo in ran:
if _count == znfo:
wz = True
_count += 1
if wz == True:
spaceBtn(round(i-1),j-1,i,j)
wz = False
else:
Label(window,text=jnfo,font=('微软雅黑',10),relief='ridge',bg='grey').place(x=j*36,y=i*38,width=30,height=30)
j=0
i+=1
for x in range(0,9):
numBtn(x+1)
Button(window,text='提示',command=tipSs).place(x=50,y=430)
bgm = Button(window,text='♫',font=('楷体',7),relief='sunken',bg='green',command=lambda:pauseOr(bgm)).place(x=365,y=11)
re = Label(window,text='剩余数字数量:'+str(dwc)+' 难度等级:'+str(difficulty),relief='sunken')
re.place(x=185,y=470)
steP = Label(window,text='步数:'+str(steps)+' 正确:'+str(rights)+' 错误:'+str(wrongs),relief='sunken')
steP.place(x=5,y=470)
window.mainloop()