24点游戏python版
问题描述与规则
24点游戏是经典的纸牌益智游戏。常见游戏规则:从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
游戏要求
基本要求
随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式。提高要求
用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。其他要求
1.程序风格良好(使用自定义注释模板)
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中
功能实现
界面部分
界面部分,我采用Pyqt5这个库,利用QT,自动生成界面,下面是界面部分的代码
def setupUi(self, Form): self.V_Life = 3 #初始生命 self.V_Score = 0 #初始分数 Form.setObjectName("Form") #主窗口 Form.resize(706, 386) #主窗口大小 Form.setStyleSheet("#Form{border-image: url(image/59.png);}") #给主窗口加背景图片 #控件 self.handPoke = QtWidgets.QPushButton(Form) self.handPoke.setGeometry(QtCore.QRect(90, 280, 71, 31)) self.handPoke.setObjectName("handPoke") self.poke_1 = QtWidgets.QLabel(Form) self.poke_1.setGeometry(QtCore.QRect(60, 30, 91, 161)) self.poke_1.setObjectName("poke_1") self.lineEdit = QtWidgets.QLineEdit(Form) self.lineEdit.setGeometry(QtCore.QRect(90, 230, 311, 31)) self.lineEdit.setObjectName("lineEdit") self.poke_4 = QtWidgets.QLabel(Form) self.poke_4.setGeometry(QtCore.QRect(450, 30, 91, 161)) self.poke_4.setObjectName("poke_4") self.poke_2 = QtWidgets.QLabel(Form) self.poke_2.setGeometry(QtCore.QRect(190, 30, 91, 161)) self.poke_2.setObjectName("poke_2") self.poke_3 = QtWidgets.QLabel(Form) self.poke_3.setGeometry(QtCore.QRect(320, 30, 91, 161)) self.poke_3.setObjectName("poke_3") self.shuRu = QtWidgets.QLabel(Form) self.shuRu.setGeometry(QtCore.QRect(10, 220, 71, 51)) self.shuRu.setObjectName("shuRu") self.queDing = QtWidgets.QPushButton(Form) self.queDing.setGeometry(QtCore.QRect(200, 280, 75, 31)) self.queDing.setObjectName("queDing") self.quXiao = QtWidgets.QPushButton(Form) self.quXiao.setGeometry(QtCore.QRect(310, 280, 75, 31)) self.quXiao.setObjectName("quXiao") self.timer = QBasicTimer() #实例化QBasicTimer,用于计时器功能 self.step = 0 #时间增加速度 self.time = QtWidgets.QProgressBar(Form) self.time.setGeometry(QtCore.QRect(90, 330, 341, 23)) self.time.setMaximum(60) self.time.setProperty("value", 0) self.time.setObjectName("time") self.label = QtWidgets.QLabel(Form) self.label.setGeometry(QtCore.QRect(50, 330, 31, 21)) self.label.setObjectName("label") self.label_life = QtWidgets.QLabel(Form) self.label_life.setGeometry(QtCore.QRect(550, 50, 31, 16)) self.label_life.setObjectName("label_life") self.label_ = QtWidgets.QLabel(Form) self.label_.setGeometry(QtCore.QRect(550, 100, 31, 16)) self.label_.setObjectName("label_") self.life = QtWidgets.QLCDNumber(Form) self.life.setGeometry(QtCore.QRect(590, 50, 64, 23)) self.life.setObjectName("life") self.Score = QtWidgets.QLCDNumber(Form) self.Score.setGeometry(QtCore.QRect(590, 100, 64, 23)) self.Score.setObjectName("Score") self.life.setDigitCount(5) self.life.setMode(QLCDNumber.Dec) self.life.display(self.V_Life) self.Score.display(self.V_Score) self.life.setStyleSheet("QLCDNumber{border: 1px solid black;color:red}") #设置QLCD显示数字的颜色,同时增加1pxd黑色边框 self.life.setSegmentStyle(QLCDNumber.Flat) self.Score.setStyleSheet("QLCDNumber{border: 1px solid black;color:red}") #设置QLCD显示数字的颜色,同时增加1pxd黑色边框 self.Score.setSegmentStyle(QLCDNumber.Flat) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "24点游戏")) self.handPoke.setText(_translate("Form", "发牌")) self.poke_1.setText(_translate("Form", "扑克牌1")) self.poke_4.setText(_translate("Form", "扑克牌4")) self.poke_2.setText(_translate("Form", "扑克牌2")) self.poke_3.setText(_translate("Form", "扑克牌3")) self.shuRu.setText(_translate("Form", " 输入算式")) self.queDing.setText(_translate("Form", "确定")) self.quXiao.setText(_translate("Form", "结束游戏")) self.time.setFormat(_translate("Form", "%p")) self.label.setText(_translate("Form", " 时间")) self.label_life.setText(_translate("Form", "生命")) self.label_.setText(_translate("Form", "得分")) self.handPoke.clicked.connect(self.handpoke) #点击事件:点击发牌按钮,触发发牌 self.handPoke.clicked.connect(self.tiMer) #点击事件:点击发牌按钮,触发计时 self.queDing.clicked.connect(self.in_enter) #点击事件:点击确定按钮,触发提交算式功能 self.quXiao.clicked.connect(self.Close) #点击事件:点击结束游戏按钮,触发程序退出功能 self.show_messsage() #提示框,游戏开始时进行提示
核心算法部分
算法部分不是自己的原创,借鉴的网上一位大佬的(原文章的链接我不小心弄丢了,十分抱歉,若是有人看到可以在评论区留下原文章),然后说一下这个算法吧,这个算法就是用将牌面的4个数字与3个运算符进行全排列组合,如果有组合满足结果为24,将此公式保存列表mylist,当用户输入公式,再和这个列表mylist中进行匹配,只要有一个匹配成功就进行下一关,分数加10分若无则生命值减1,进入下一关。具体代码实现如下#算法 def Algorithm24(self): self.lst=[self.A1,self.A2,self.A3,self.A4] self.exps = ('((%s%s%s)%s%s)%s%s', '(%s%s%s)%s(%s%s%s)', '(%s%s(%s%s%s))%s%s', '%s%s((%s%s%s)%s%s)', '%s%s(%s%s(%s%s%s))') self.ops = r'+-*/' self.result = [] #Python允许函数的嵌套定义 #这个函数对字符串表达式求值并验证是否等于24 def check(exp): try: #有可能会出现除0异常,所以放到异常处理结构中 return int(eval(exp)) == 24 except: return False #全排列,枚举4个数的所有可能顺序 for a in permutations(self.lst): #查找4个数的当前排列能实现24的表达式 t = [exp%(a[0],op1,a[1],op2,a[2],op3,a[3])for op1 in self.ops for op2 in self.ops for op3 in self.ops for exp in self.exps if check(exp %(a[0],op1,a[1],op2,a[2],op3,a[3]))] if t: self.result.append(t) self.mylist = myList = [x for j in self.result for x in j]#将多个列表合并为一个列表,将所有可能的公式存储在mylist中 return self.result
各类响应事件
发牌事件
首先我在本地保存了52张扑克牌素材,编号序,1-4为A的四种花色, 5-8为2的四种花色,依次按照这个顺序编排好,然后建立一个imas[]列表,用于储存这52张牌的路径,路径保存好之后,利用random.samole随机从imgs中抽出四个不重复的路径,保存在我定义的randomlist列表中,然后利用setPixmap(),以及QtGui中的QPixmap(),setScaledContents(True)方法在我的标签控件中进行显示,使得牌面能够显示在界面中。self.imgs = []#定义一个imgs列表,用于保存本地图片的路径 for j in range(1, 53): self.imgs.insert(j, './image/' + str(j) + '.png') #将路径添加到imgs self.randomlist = random.sample(self.imgs, 4) #选择4个随机路径,保存在randomlist中 self.poke_1.setPixmap(QtGui.QPixmap(self.randomlist[0])) #插入图片到poke标签中 self.poke_2.setPixmap(QtGui.QPixmap(self.randomlist[1])) self.poke_3.setPixmap(QtGui.QPixmap(self.randomlist[2])) self.poke_4.setPixmap(QtGui.QPixmap(self.randomlist[3])) self.poke_1.setScaledContents(True) #显示poke self.poke_2.setScaledContents(True) self.poke_3.setScaledContents(True) self.poke_4.setScaledContents(True)
为了使得所发牌面与1~13数字相对应,首先我利用正则表达式将刚才存储在randomlist列表4个字符串路径中的数字提取出来,同时调用join函数去掉[]然后分别放在我定义四个变量中(aa bb cc dd)。然后设计绑定数字的方法,以变量aa为例,如果aa2|aa4,则返回变量A1=1,若aa6|aa8,则返回变量A1=2,按照此规律绑定了第一张牌,其他牌的方法和此方法一样。以下是具体实现代码(判断条件之前用的是,1<=aa<=4,但总是匹配的数字与牌面不一致,所以换了个判断方法,不过我认为之前的方法应该是可以的,可能自己当时某部分写错了,感兴趣可以试一下)
self.aa = ''.join(re.findall("\d+", self.randomlist[0])) #利用正则表达式将randomlist列表路径字符串中的数字提取,同时去掉[] self.bb = ''.join(re.findall("\d+", self.randomlist[1])) self.cc = ''.join(re.findall("\d+", self.randomlist[2])) self.dd = ''.join(re.findall("\d+", self.randomlist[3])) self.BD1() self.BD2() self.BD3() self.BD4() #将扑克牌1的扑克与1~13的数字进行绑定 def BD1(self): if (self.aa=='1')|(self.aa=='2')|(self.aa=='3')|(self.aa=='4'): self.A1=1 elif (self.aa=='5')|(self.aa=='6')|(self.aa=='7')|(self.aa=='8'): self.A1=2 elif (self.aa=='9')|(self.aa=='10')|(self.aa=='11')|(self.aa=='12'): self.A1=3 elif (self.aa=='13')|(self.aa=='14')|(self.aa=='15')|(self.aa=='16'): self.A1=4 elif (self.aa=='17')|(self.aa=='18')|(self.aa=='19')|(self.aa=='20'): self.A1=5 elif (self.aa=='21')|(self.aa=='22')|(self.aa=='23')|(self.aa=='24'): self.A1=6 elif (self.aa=='25')|(self.aa=='26')|(self.aa=='27')|(self.aa=='28'): self.A1=7 elif (self.aa=='29')|(self.aa=='30')|(self.aa=='31')|(self.aa=='32'): self.A1=8 elif (self.aa=='33')|(self.aa=='34')|(self.aa=='35')|(self.aa=='36'): self.A1=9 elif (self.aa=='37')|(self.aa=='38')|(self.aa=='39')|(self.aa=='40'): self.A1=10 elif (self.aa=='41')|(self.aa=='42')|(self.aa=='43')|(self.aa=='44'): self.A1=11 elif (self.aa=='45')|(self.aa=='46')|(self.aa=='47')|(self.aa=='48'): self.A1=12 else: self.A1=13 return self.A1
计时器事件
计时功能由进度条实现,如果进度条进度完成,生命值减少1,同时调用发牌方法,刷新进度条,重新计时,代码实现如下#计时功能 def tiMer(self,value): self.timer.start(60,self) #计时增加功能 def timerEvent(self, e): if self.step >= 60: # self.timer.stop() self.time.reset() self.step=0 self.handpoke() self.LI_FE() self.step = self.step + 0.05 self.time.setValue(self.step)
确定事件
确定事件主要实现两个功能,1对编辑框中的公式进行接收2.点击确定后调用公式库,在mylist中进行匹配,只要有一个匹配成功就进行下一关,分数加10分若无则生命值减1,代码部分如下# 确定提交功能 def in_enter(self): self.ss=self.lineEdit.text() if self.ss in self.mylist: self.SCO_RE() self.handpoke() else: self.LI_FE() self.handpoke() self.time.reset() self.step = 0 self.step = self.step + 0.5 self.time.setValue(self.step)
计算分数与生命
这部分就直接放代码#减少生命功能 def LI_FE(self): self.V_Life = self.V_Life - 1 if self.V_Life>0: self.life.display(self.V_Life) else: self.life.display(self.V_Life) s = u'24点游戏得分:\r\n' f = codecs.open("Toplist.txt", 'a', 'utf-8') f.write(s+'\r\n') f.write(str(self.V_Score)+"\r\n") f.close() self.closeEvent(1) return self.V_Life #增加分数功能 def SCO_RE(self):#得分计算 self.V_Score=self.V_Score+10 self.Score.display(self.V_Score) return self.V_Score
游戏结束与提示框功能
直接上代码# 提示框 def show_messsage(self): QMessageBox.about(self,'游戏说明',"欢迎来到24点游戏,每局游戏有3生命值,您必须在规定时间内输入算式,否则生命值减1,输入错误生命值也会减1,当生命值为0时,游戏结束,点击发牌开始游戏,点击确定输入算式,点击结束游戏,游戏退出,祝您体验愉快") #生命值为0,弹出是否继续游戏功能 def closeEvent(self,event): reply = QMessageBox.question(self, '结束提示', '您的生命值用完!游戏结束,是否要再来一次', QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.V_Life = 3 self.V_Score = 0 self.handpoke() else: self.Close() #游戏退出功能 def Close(self): self.sz=QApplication.instance() self.sz.quit()
运行截图
游戏提示
开始界面
发牌界面
输出正确
输入错误
游戏结束
查看分数
附上完整代码
``` # -*- coding: utf-8 -*- # @Time :2018年10月5日17:02分 # @Author : 刘霖 from PyQt5 import QtCore, QtGui, QtWidgets #界面 from itertools import permutations #使用全排列 from PyQt5.QtWidgets import * #界面 import random #产生随机数 import re #导入这个,是为了使用正则表达式,提取字符串中的数字 import codecs #文件操作 from PyQt5.QtCore import QBasicTimer #用于计时功能 import os os.environ["CUDA_VISIBLE_DEVICES"] = "-1" #解决内存不足 import sys class Ui_Form(QWidget): def setupUi(self, Form): self.V_Life = 3 #初始生命 self.V_Score = 0 #初始分数 Form.setObjectName("Form") #主窗口 Form.resize(706, 386) #主窗口大小 Form.setStyleSheet("#Form{border-image: url(image/59.png);}") #给主窗口加背景图片 #控件 self.handPoke = QtWidgets.QPushButton(Form) self.handPoke.setGeometry(QtCore.QRect(90, 280, 71, 31)) self.handPoke.setObjectName("handPoke") self.poke_1 = QtWidgets.QLabel(Form) self.poke_1.setGeometry(QtCore.QRect(60, 30, 91, 161)) self.poke_1.setObjectName("poke_1") self.lineEdit = QtWidgets.QLineEdit(Form) self.lineEdit.setGeometry(QtCore.QRect(90, 230, 311, 31)) self.lineEdit.setObjectName("lineEdit") self.poke_4 = QtWidgets.QLabel(Form) self.poke_4.setGeometry(QtCore.QRect(450, 30, 91, 161)) self.poke_4.setObjectName("poke_4") self.poke_2 = QtWidgets.QLabel(Form) self.poke_2.setGeometry(QtCore.QRect(190, 30, 91, 161)) self.poke_2.setObjectName("poke_2") self.poke_3 = QtWidgets.QLabel(Form) self.poke_3.setGeometry(QtCore.QRect(320, 30, 91, 161)) self.poke_3.setObjectName("poke_3") self.shuRu = QtWidgets.QLabel(Form) self.shuRu.setGeometry(QtCore.QRect(10, 220, 71, 51)) self.shuRu.setObjectName("shuRu") self.queDing = QtWidgets.QPushButton(Form) self.queDing.setGeometry(QtCore.QRect(200, 280, 75, 31)) self.queDing.setObjectName("queDing") self.quXiao = QtWidgets.QPushButton(Form) self.quXiao.setGeometry(QtCore.QRect(310, 280, 75, 31)) self.quXiao.setObjectName("quXiao") self.timer = QBasicTimer() #实例化QBasicTimer,用于计时器功能 self.step = 0 #时间增加速度 self.time = QtWidgets.QProgressBar(Form) self.time.setGeometry(QtCore.QRect(90, 330, 341, 23)) self.time.setMaximum(60) self.time.setProperty("value", 0) self.time.setObjectName("time") self.label = QtWidgets.QLabel(Form) self.label.setGeometry(QtCore.QRect(50, 330, 31, 21)) self.label.setObjectName("label") self.label_life = QtWidgets.QLabel(Form) self.label_life.setGeometry(QtCore.QRect(550, 50, 31, 16)) self.label_life.setObjectName("label_life") self.label_ = QtWidgets.QLabel(Form) self.label_.setGeometry(QtCore.QRect(550, 100, 31, 16)) self.label_.setObjectName("label_") self.life = QtWidgets.QLCDNumber(Form) self.life.setGeometry(QtCore.QRect(590, 50, 64, 23)) self.life.setObjectName("life") self.Score = QtWidgets.QLCDNumber(Form) self.Score.setGeometry(QtCore.QRect(590, 100, 64, 23)) self.Score.setObjectName("Score") self.life.setDigitCount(5) self.life.setMode(QLCDNumber.Dec) self.life.display(self.V_Life) self.Score.display(self.V_Score) self.life.setStyleSheet("QLCDNumber{border: 1px solid black;color:red}") #设置QLCD显示数字的颜色,同时增加1pxd黑色边框 self.life.setSegmentStyle(QLCDNumber.Flat) self.Score.setStyleSheet("QLCDNumber{border: 1px solid black;color:red}") #设置QLCD显示数字的颜色,同时增加1pxd黑色边框 self.Score.setSegmentStyle(QLCDNumber.Flat) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "24点游戏")) self.handPoke.setText(_translate("Form", "发牌")) self.poke_1.setText(_translate("Form", "扑克牌1")) self.poke_4.setText(_translate("Form", "扑克牌4")) self.poke_2.setText(_translate("Form", "扑克牌2")) self.poke_3.setText(_translate("Form", "扑克牌3")) self.shuRu.setText(_translate("Form", " 输入算式")) self.queDing.setText(_translate("Form", "确定")) self.quXiao.setText(_translate("Form", "结束游戏")) self.time.setFormat(_translate("Form", "%p")) self.label.setText(_translate("Form", " 时间")) self.label_life.setText(_translate("Form", "生命")) self.label_.setText(_translate("Form", "得分")) self.handPoke.clicked.connect(self.handpoke) #点击事件:点击发牌按钮,触发发牌 self.handPoke.clicked.connect(self.tiMer) #点击事件:点击发牌按钮,触发计时 self.queDing.clicked.connect(self.in_enter) #点击事件:点击确定按钮,触发提交算式功能 self.quXiao.clicked.connect(self.Close) #点击事件:点击结束游戏按钮,触发程序退出功能 self.show_messsage() #提示框,游戏开始时进行提示 # 提示框 def show_messsage(self): QMessageBox.about(self,'游戏说明',"欢迎来到24点游戏,每局游戏有3生命值,您必须在规定时间内输入算式,否则生命值减1,输入错误生命值也会减1,当生命值为0时,游戏结束,点击发牌开始游戏,点击确定输入算式,点击结束游戏,游戏退出,祝您体验愉快") #生命值为0,弹出是否继续游戏功能 def closeEvent(self,event): reply = QMessageBox.question(self, '结束提示', '您的生命值用完!游戏结束,是否要再来一次', QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.V_Life = 3 self.V_Score = 0 self.handpoke() else: self.Close() #游戏退出功能 def Close(self): self.sz=QApplication.instance() self.sz.quit() #计时功能 def tiMer(self,value): self.timer.start(60,self) #计时增加功能 def timerEvent(self, e): if self.step >= 60: # self.timer.stop() self.time.reset() self.step=0 self.handpoke() self.LI_FE() self.step = self.step + 0.05 self.time.setValue(self.step) #减少生命功能 def LI_FE(self): self.V_Life = self.V_Life - 1 if self.V_Life>0: self.life.display(self.V_Life) else: self.life.display(self.V_Life) s = u'24点游戏得分:\r\n' f = codecs.open("Toplist.txt", 'a', 'utf-8') f.write(s+'\r\n') f.write(str(self.V_Score)+"\r\n") f.close() self.closeEvent(1) return self.V_Life #增加分数功能 def SCO_RE(self):#得分计算 self.V_Score=self.V_Score+10 self.Score.display(self.V_Score) return self.V_Score # 确定提交功能 def in_enter(self): self.ss=self.lineEdit.text() if self.ss in self.mylist: self.SCO_RE() self.handpoke() else: self.LI_FE() self.handpoke() self.time.reset() self.step = 0 self.step = self.step + 0.5 self.time.setValue(self.step) #发牌功能 def handpoke(self): self.life.display(self.V_Life) self.Score.display(self.V_Score) self.imgs = []#定义一个imgs列表,用于保存本地图片的路径 for j in range(1, 53): self.imgs.insert(j, './image/' + str(j) + '.png') #将路径添加到imgs self.randomlist = random.sample(self.imgs, 4) #选择4个随机路径,保存在randomlist中 self.poke_1.setPixmap(QtGui.QPixmap(self.randomlist[0])) #插入图片到poke标签中 self.poke_2.setPixmap(QtGui.QPixmap(self.randomlist[1])) self.poke_3.setPixmap(QtGui.QPixmap(self.randomlist[2])) self.poke_4.setPixmap(QtGui.QPixmap(self.randomlist[3])) self.poke_1.setScaledContents(True) #显示poke self.poke_2.setScaledContents(True) self.poke_3.setScaledContents(True) self.poke_4.setScaledContents(True) self.Algorithm24() #将扑克牌1的扑克与1~13的数字进行绑定 def BD1(self): if (self.aa=='1')|(self.aa=='2')|(self.aa=='3')|(self.aa=='4'): self.A1=1 elif (self.aa=='5')|(self.aa=='6')|(self.aa=='7')|(self.aa=='8'): self.A1=2 elif (self.aa=='9')|(self.aa=='10')|(self.aa=='11')|(self.aa=='12'): self.A1=3 elif (self.aa=='13')|(self.aa=='14')|(self.aa=='15')|(self.aa=='16'): self.A1=4 elif (self.aa=='17')|(self.aa=='18')|(self.aa=='19')|(self.aa=='20'): self.A1=5 elif (self.aa=='21')|(self.aa=='22')|(self.aa=='23')|(self.aa=='24'): self.A1=6 elif (self.aa=='25')|(self.aa=='26')|(self.aa=='27')|(self.aa=='28'): self.A1=7 elif (self.aa=='29')|(self.aa=='30')|(self.aa=='31')|(self.aa=='32'): self.A1=8 elif (self.aa=='33')|(self.aa=='34')|(self.aa=='35')|(self.aa=='36'): self.A1=9 elif (self.aa=='37')|(self.aa=='38')|(self.aa=='39')|(self.aa=='40'): self.A1=10 elif (self.aa=='41')|(self.aa=='42')|(self.aa=='43')|(self.aa=='44'): self.A1=11 elif (self.aa=='45')|(self.aa=='46')|(self.aa=='47')|(self.aa=='48'): self.A1=12 else: self.A1=13 return self.A1 # 将扑克牌2的扑克与1~13的数字进行绑定 def BD2(self): if (self.bb == '1') | (self.bb == '2') | (self.bb == '3') | (self.bb == '4'): self.A2 = 1 elif (self.bb == '5') | (self.bb == '6') | (self.bb == '7') | (self.bb == '8'): self.A2 = 2 elif (self.bb == '9') | (self.bb == '10') | (self.bb == '11') | (self.bb == '12'): self.A2 = 3 elif (self.bb == '13') | (self.bb == '14') | (self.bb == '15') | (self.bb == '16'): self.A2 = 4 elif (self.bb == '17') | (self.bb == '18') | (self.bb == '19') | (self.bb == '20'): self.A2 = 5 elif (self.bb == '21') | (self.bb == '22') | (self.bb == '23') | (self.bb == '24'): self.A2 = 6 elif (self.bb == '25') | (self.bb == '26') | (self.bb == '27') | (self.bb == '28'): self.A2 = 7 elif (self.bb == '29') | (self.bb == '30') | (self.bb == '31') | (self.bb == '32'): self.A2 = 8 elif (self.bb == '33') | (self.bb == '34') | (self.bb == '35') | (self.bb == '36'): self.A2 = 9 elif (self.bb == '37') | (self.bb == '38') | (self.bb == '39') | (self.bb == '40'): self.A2 = 10 elif (self.bb == '41') | (self.bb == '42') | (self.bb == '43') | (self.bb == '44'): self.A2 = 11 elif (self.bb == '45') | (self.bb == '46') | (self.bb == '47') | (self.bb == '48'): self.A2 = 12 else: self.A2 = 13 return self.A2 # 将扑克牌3的扑克与1~13的数字进行绑定 def BD3(self): if (self.cc == '1') | (self.cc == '2') | (self.cc == '3') | (self.cc == '4'): self.A3 = 1 elif (self.cc == '5') | (self.cc == '6') | (self.cc == '7') | (self.cc == '8'): self.A3 = 2 elif (self.cc == '9') | (self.cc == '10') | (self.cc == '11') | (self.cc == '12'): self.A3 = 3 elif (self.cc == '13') | (self.cc == '14') | (self.cc == '15') | (self.cc == '16'): self.A3 = 4 elif (self.cc == '17') | (self.cc == '18') | (self.cc == '19') | (self.cc == '20'): self.A3 = 5 elif (self.cc == '21') | (self.cc == '22') | (self.cc == '23') | (self.cc == '24'): self.A3 = 6 elif (self.cc == '25') | (self.cc == '26') | (self.cc == '27') | (self.cc == '28'): self.A3 = 7 elif (self.cc == '29') | (self.cc == '30') | (self.cc == '31') | (self.cc == '32'): self.A3 = 8 elif (self.cc == '33') | (self.cc == '34') | (self.cc == '35') | (self.cc == '36'): self.A3 = 9 elif (self.cc == '37') | (self.cc == '38') | (self.cc == '39') | (self.cc == '40'): self.A3 = 10 elif (self.cc == '41') | (self.cc == '42') | (self.cc == '43') | (self.cc == '44'): self.A3 = 11 elif (self.cc == '45') | (self.cc == '46') | (self.cc == '47') | (self.cc == '48'): self.A3 = 12 else: self.A3 = 13 return self.A3 # 将扑克牌4的扑克与1~13的数字进行绑定 def BD4(self): if (self.dd == '1') | (self.dd == '2') | (self.dd == '3') | (self.dd == '4'): self.A4 = 1 elif (self.dd == '5') | (self.dd == '6') | (self.dd == '7') | (self.dd == '8'): self.A4 = 2 elif (self.dd == '9') | (self.dd == '10') | (self.dd == '11') | (self.dd == '12'): self.A4 = 3 elif (self.dd == '13') | (self.dd == '14') | (self.dd == '15') | (self.dd == '16'): self.A4 = 4 elif (self.dd == '17') | (self.dd == '18') | (self.dd == '19') | (self.dd == '20'): self.A4 = 5 elif (self.dd == '21') | (self.dd == '22') | (self.dd == '23') | (self.dd == '24'): self.A4 = 6 elif (self.dd == '25') | (self.dd == '26') | (self.dd == '27') | (self.dd == '28'): self.A4 = 7 elif (self.dd == '29') | (self.dd == '30') | (self.dd == '31') | (self.dd == '32'): self.A4 = 8 elif (self.dd == '33') | (self.dd == '34') | (self.dd == '35') | (self.dd == '36'): self.A4 = 9 elif (self.dd == '37') | (self.dd == '38') | (self.dd == '39') | (self.dd == '40'): self.A4 = 10 elif (self.dd == '41') | (self.dd == '42') | (self.dd == '43') | (self.dd == '44'): self.A4 = 11 elif (self.dd == '45') | (self.dd == '46') | (self.dd == '47') | (self.dd == '48'): self.A4 = 12 else: self.A4 = 13 return self.A4 #算法 def Algorithm24(self): self.lst=[self.A1,self.A2,self.A3,self.A4] self.exps = ('((%s%s%s)%s%s)%s%s', '(%s%s%s)%s(%s%s%s)', '(%s%s(%s%s%s))%s%s', '%s%s((%s%s%s)%s%s)', '%s%s(%s%s(%s%s%s))') self.ops = r'+-*/' self.result = [] #Python允许函数的嵌套定义 #这个函数对字符串表达式求值并验证是否等于24 def check(exp): try: #有可能会出现除0异常,所以放到异常处理结构中 return int(eval(exp)) == 24 except: return False #全排列,枚举4个数的所有可能顺序 for a in permutations(self.lst): #查找4个数的当前排列能实现24的表达式 t = [exp%(a[0],op1,a[1],op2,a[2],op3,a[3])for op1 in self.ops for op2 in self.ops for op3 in self.ops for exp in self.exps if check(exp %(a[0],op1,a[1],op2,a[2],op3,a[3]))] if t: self.result.append(t) self.mylist = myList = [x for j in self.result for x in j]#将多个列表合并为一个列表,将所有可能的公式存储在mylist中 return self.result if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) Form=QtWidgets.QMainWindow() ui = Ui_Form() ui.setupUi(Form) Form.show() sys.exit(app.exec_()) ```