早期的一个项目,创作品思想源自于数字华容道(n-puzzle),是一种智力游戏,十五数字推盘游戏的板上会有十五个方块和一个大小相当于一个方块的空位(供方块移动之用),当15个数字依次排序并且最后一个格子为空位即代表挑战成功。
首先把问题场景化,通过程序游戏的形式,让大家直观简单地操作,容易接受,也便于交流和传播,同时在游戏中思考和解决问题。
初始程序界面
挑战成功完成的界面
实现过程和完整代码:
程序UI没有使用PyQt,而是用Python自带的tkinter库,界面元素主要使用按钮来完成。
每次开局,都采取随机打乱方式,但是需要一些注意,必须要保证有解(两两交换!)
import tkinter as tk
import tkinter.messagebox
import random
root = tk.Tk()
root.geometry("400x420")
root.title("益智游戏—数字华容道")
lb1=tk.Label(root,text="请移动板上的方块,让所有的方块顺着数字的次序排列。",font=("",11))
lb1.grid(padx=5,pady=5,row=0,column=1,columnspan=4)
count=0
lb2=tk.Label(root,text="完成步数: " str(count),font=("",10))
lb2.grid(padx=2,pady=2,row=5,column=3)
id=[i for i in range(15)]
imgid=[i 1 for i in range(16)]
finish=[0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15]
def msg():
tk.messagebox.showinfo(title="恭喜!",message="恭喜你,挑战成功!")
def move(index, t,r,c):
#print(index,t,r,c)
k=r-1 (c-1)*4
r0=imgid.index(16)%4 1
c0=imgid.index(16)//4 1
k0=r0-1 (c0-1)*4
#print(k,k0)
def change():
buttons[k].config(text="16",bg="white",fg="white")
buttons[k0].config(text=imgid[k], bg="tan",fg="black")
imgid[k],imgid[k0]=imgid[k0],imgid[k]
tmp=[ imgid.index(i 1) for i in range(16)]
#print(tmp)
global count
count=count 1
lb2.config(text="完成步数: " str(count))
if(tmp==finish):
msg()
if(r==r0 and c0-c==1) or (r==r0 and c0-c==-1) or (r0-r==1 and c==c0) or (r0-r==-1 and c==c0):
#print(k,t,"move right")
change()
#print(imgid)
buttons = []
#随机两两交换,保证有解!
def shuffleid():
for i in range(8):
a=random.choice(id)
b=random.choice(id)
c=random.choice(id)
d=random.choice(id)
while (a==b or a==c or a==d or b==c or b==d or c==d):
a=random.choice(id)
b=random.choice(id)
c=random.choice(id)
d=random.choice(id)
#print(a,b,c,d)
imgid[a],imgid[b]=imgid[b],imgid[a]
imgid[c],imgid[d]=imgid[d],imgid[c]
#print(imgid)
def init():
shuffleid()
for i in imgid:
n=i
if(n==16):
fg="white"
bg="white"
else:
fg="black"
bg="tan"
r=imgid.index(i)%4 1
c=imgid.index(i)//4 1
num=imgid.index(i)
button = tk.Button(root, bg=bg, text=n,fg=fg,font=("",12),width=10,height=4,relief=tk.GROOVE, command=lambda index=num, n=n,r=r,c=c: move(index, n,r,c))
button.grid(padx=4, pady=4, row=r, column=c)
# Add a reference to the button to 'buttons'
buttons.append(button)
init()
def restart():
shuffleid()
global count
count=0
for i in imgid:
n=i
if(n==16):
fg="white"
bg="white"
else:
fg="black"
bg="tan"
r=imgid.index(i)%4 1
c=imgid.index(i)//4 1
num=imgid.index(i)
buttons[imgid.index(i)].config(text=i,bg=bg,fg=fg)
#print(imgid)
bt1=tk.Button(root,text="重新开始",command=restart)
bt1.grid(padx=2,pady=2,row=5,column=2,columnspan=1)
root.mainloop()