传统用扑克牌算24点游戏用于小学低中段学生训练四则运算效果不错,也可用于防止老年痴呆。本项目模拟传统扑克24点算法,由计算机发4张牌,人工在下方输入算式,算式只能用加减乘除、左右括号和显示的4个数字(各个数字均用一次,且只能用一次),按“验证结果”即可判定你的输入是否正确有效;完成后,或无解题,可按“重新发牌”来继续游戏。本项目主要由tkinter界面、随机发牌、验证结果三大部分构成。游戏运行结果如图所示:
一、界面生成:
利用Page 4.7 for Python这款可视化tkinter GUI界面生成工具来布置界面,放Label1~Label4四个标签组件用于显示扑克牌,扑克牌用c1~c13.jpg(草花)、f1~f13.jpg(方块)、h1~h13.jpg(黑桃)和r1~r13.jpg(红桃)这些JPG文件来表达,放在image文件夹下。由于tkinter不能支持JPG文件,这里用了pillow库实现。下面这段代码实现显示一张红桃A:
from PIL import Image as pImage
from PIL import ImageTk as pImageTk
from tkinter import *
root=Tk()
Label1 = Label(root) #建立标签
im1=pImage.open(".\\image\\r1.jpg") #打开图片文件
p1=pImageTk.PhotoImage(im1) #建立与tkinter适用的接口
Label1['image']=p1 #把图片放入标签
Label1.image=p1 #这句话不可不放,否则影响及时更新
Label1.pack()
除了Label组件外,还放入一个单行文本框(Text Var设置为myEval),验证结果按钮(text属性设置为'''验证结果'',command设置为judge),重新发牌按钮(text属性设置为'''重新发牌''',command设置为again)。界面设计完成后,使用菜单生成Python程序game24dian.py和相关的支持程序game24dian_support.py。
二、随机发牌
用Idle打开game24dian_support.py文件,修改完成again()函数。先随机选四个花色,再随机找四个数字,以组合成四张牌。直接上源码:
def again():
'''发牌,从四种花色中抽1-10张牌中的4种'''
global huase,shuzi
#初始化表达式
myEval.set("")
#选花色
huase=[random.choice("rhfc") for i in range(4)]
#选牌
shuzi=[random.randint(1,10) for i in range(4)]
#组合生成四张牌的文件名,要用PIL库才能在tkinter中使用jpg文件
im1=pImage.open(".\\image\\" + huase[0] + str(shuzi[0]) + ".jpg")
im2=pImage.open(".\\image\\" + huase[1] + str(shuzi[1]) + ".jpg")
im3=pImage.open(".\\image\\" + huase[2] + str(shuzi[2]) + ".jpg")
im4=pImage.open(".\\image\\" + huase[3] + str(shuzi[3]) + ".jpg")
p1=pImageTk.PhotoImage(im1)
p2=pImageTk.PhotoImage(im2)
p3=pImageTk.PhotoImage(im3)
p4=pImageTk.PhotoImage(im4)
#在标签中设置图片
w.Label1['image'], w.Label2['image'], w.Label3['image'], w.Label4['image'] = p1, p2, p3, p4
w.Label1.image, w.Label2.image, w.Label3.image, w.Label4.image = p1, p2, p3, p4
sys.stdout.flush()
三、验证结果
用Idle打开game24dian_support.py文件,完成judge()函数。先判断输入的表达式值是否为24,如果是抽取表达式中的数字并排序,与发牌时生成的有序数字序列比较,完全相等,则说明用户输入正确,否则提示不正确。直接上源码:
def judge():
'''判断计算输入是否正确'''
if myEval.get() and eval(myEval.get())==24:
#对输入的表达式中抽取数并排序
lst1 = re.findall('\d', myEval.get())
lst1 = sorted(map(int, lst1))
#对生成的数字列表进行排序
lst2=sorted(shuzi)
#比较列表,进行判断
if lst1==lst2:
messagebox.showinfo("祝贺你!", myEval.get()+"=24,\n你算对了,真了不起!")
else:
messagebox.showinfo("注意:", "每个数字都要用,且只能用一次。")
else:
messagebox.showinfo("不正确:", "请输入正确的表达式,使得计算结果为24。")
sys.stdout.flush()