问题描述与规则
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为例,如果aa1|aa2|aa3|aa4,则返回变量A1=1,若aa5|aa6|aa7|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_())
```