#5.6日更新,已经实现了实现任意个数字,计算达到任意目标值。例如5张扑克牌计算72点,60点
#计算5张扑克牌需要112500次迭代(计算4张只需要2250次)慢了很多
#计算6张扑克牌需要十分钟吧
#-----------------------------------------------------
#程序功能: 随机生成或者用户输入4个1~13的值,本程序可以计算出24点的解决方案
#递归原理看函数cal
#比较爽的,一个是用了递归,一个是学习了用fractions模块实现分数输出
#理论上,本程序可以扩展到任意长序列,结果任意指定而仅需修改几个简单的值实现
#几个好玩的测试用例: 3,3,8,8; 1,6,6,8; 1,4,5,6
#【 8÷3= 8/3】【 3-8/3= 1/3】【 8÷1/3= 24】
#废话少说,上代码
#----------------------------------------------------
import random, easygui,copy
import fractions
global solutions
def operations(a,b,oper):
if oper==1:
c = a+b
return [c, "【 "+str(a)+"\t+\t"+str(b)+"\t= "+str(c) + "\t】\t"]
if oper==2:
if a>=b:
c = a-b
return [c, "【 "+str(a)+"\t-\t"+str(b)+"\t= "+str(c) + "\t】\t"]
else:
c = b-a
return [c, "【 "+str(b)+"\t-\t"+str(a)+"\t= "+str(c) + "\t】\t"]
if oper==3:
c = a*b
return [c, "【 "+str(a)+"\tx\t"+str(b)+"\t= "+str(c) + "\t】\t"]
if oper==4:
if abs(b) > 0.000001:
c = a/b
else:
c = 9999
return [c, "【 "+str(a)+"\t÷\t"+str(b)+"\t= "+str(c) + "\t】\t"]
if oper==5:
if abs(a) > 0.000001:
c = b/a
else:
c = 9999
return [c, "【 "+str(b)+"\t÷\t"+str(a)+"\t= "+str(c) + "\t】\t"]
def cal(F,record,answer):
global solutions
number = len(F)
if number == 1 and abs(F[0]-answer) < 0.000001:
record += "\n"
solutions.append(record)
return
for i in range(0,number-1):
for j in range (i+1,number):
childF = copy.deepcopy(F) #制作拷贝,每2个数会制作一个新拷贝
A = F[i] #第一个数
B = F[j] #第二个数
childF.remove(A) #去掉A,B
childF.remove(B)
for k in range(1,6):
copyChildF = copy.deepcopy(childF) #制作数列拷贝,每个操作再制造一个新拷贝
childInputRecord = record #制作操作字符串拷贝
C = operations(A,B,k) #计算A和B的和差积商,得到C
operResult = C[0] #分别取回计算结果和操作字符串记录
childInputRecord+=C[1]
copyChildF.append(operResult) #C和刚才剩余的2项组成下一轮的输入
cal(copyChildF,childInputRecord,answer) #下一轮
#############################################################################################
# #
# 主程序 #
# #
#############################################################################################
if __name__ == '__main__':
cardSuit = [] #最终使用的牌组,以分数形式存储
solutions = [] #解答
inputCards=[] #输入的字符型牌组,最初是自动随机生成,用户可以修改
numberSolutions =0 #解的数量
#-------------------------------输入选择游戏类型-------------------------------
softAbout = ' 计算24点的扩展程序。\n' \
' 本程序根据用户输入或随机生成的数串计算得到指定结果(例如24)\n'\
' 您可以自己指定几个数,指定希望结果。\n 本程序将给出所有可能的计算方法。'
easygui.msgbox(msg=softAbout, title = "软件说明")
gameTypeSelection = ['4', '24', '1', '13'] #默认的是24点游戏,4张牌,每张限制1~13之间
inputIllegal = True
while inputIllegal:
gameTypeSelection = easygui.multenterbox(msg = '请选择游戏类型,不改动即为普通的24点游戏。', \
title = '游戏类型选择', \
fields = ['数字个数','目标值(例如24)','数字最小限制','数字最大限制'], \
values=gameTypeSelection)
if gameTypeSelection is None:
quit()
inputIllegal = False
for item in list(gameTypeSelection):
if item == '' or not item.isdigit():
inputIllegal = True
numberNum = int(gameTypeSelection[0])
answerTarget = int(gameTypeSelection[1])
numberMin = int(gameTypeSelection[2])
numberMax = int(gameTypeSelection[3])
#-------------------------------准备阶段,输入4个数-------------------------------
for i in range(0,numberNum):
inputCards.append(str(random.randint(numberMin,numberMax)))
msgFields = []
for i in range(0,numberNum):
msgFields.append("数字" + str(i))
inputIllegal = True
while inputIllegal:
inputCards = easygui.multenterbox(msg = '计算'+str(answerTarget)+'点游戏\n本程序自动计算'+str(answerTarget)+'点\n请输入'+str(numberNum)+'个数字\n(也可不修改随机生成的数字)', \
title = '计算'+str(answerTarget)+'点', \
fields = msgFields, \
values = inputCards)
if inputCards is None:
quit()
inputIllegal = False
for item in list(inputCards):
if item == '' or not item.isdigit() or int(item) < numberMin or int(item)>numberMax:
inputIllegal = True
for item in list(inputCards):
cardSuit.append(fractions.Fraction(item))
#--------------------------最核心的只有一行--------------------
cal(cardSuit,"",answerTarget)
#--------------------------通过转“集合”再转回来,实现字符串级别的去重-------------------
solutions = list(set(solutions))
#--------------------------显示答案---------------------------------
numberSolutions = len(solutions)
msgmsg = "牌组" + str(list(map(int,inputCards))) + "计算"+str(answerTarget)+"共有"+str(numberSolutions)+"种答案"
msgtitle = inputCards
easygui.codebox(msg=msgmsg,title=msgtitle, text=solutions)