基础24点游戏规则:
从1~13中随机选取4个正整数(可以重复),通过加、减、乘、除四则运算与加括号,
使这4个正整数在每个数不多不少使用一回的情况下,经过几次运算之后算出24
1.1 实现输入式24点计算
1.1.2 实现目标:
用户输入4个用逗号分割的正整数,使程序计算能否使用这4个数在满足基础24点游戏
规则的情况下算出24,若能则输出 数学表达式,若不能则输出 抱歉,此数组无解
1.1.3 大致思路(大思路方向,具体参见代码详细注释):
(1)大致计算方向为 把符号按顺序(顺次)插入进四个数 所以,四个数的排列与三个符号及括号
的排列方式都会对结果产生影响,这时就需要进行枚举排列情况
(2)程序接收用户输入的四个数,枚举得到其所有的排列情况,统一存储在一个列表内
(3)程序再次枚举得到三个符号所有的排列情况,也统一存储在一个列表内
(4)循环取出(遍历)四个数的排列组合情况,同时在这个循环里面再套入一个循环,再循环取
出三个符号的排列组合情况,保证不漏下任何一种组合
(5)第一次,将取出的符号直接顺次插入到四个数中间,按照运算优先级来计算,看看能否得
出24
(6)如果上面的情况无法算出24,则考虑插入括号。在4个数3个运算符的式子之间,能插入两种
括号(里面包含两个数的、里面包含三个数的)
(7)通过分析运算符的排列,判定在某个地方是否需要插入括号、插入的括号有没有意义
(8)以下是分组(+即代表可以插入 +/-,×即代表可以插入 ×/÷,÷只代表插入÷(因为有特殊考
虑÷的分类),○代表插入 +/-/×/÷ 均可):
1、(a+b)×c ○ d 2、(a+b)×(c+d) 3、a÷(b+c) ○ d 4、(a+b+c)×d 5、(a+b×c)×d
6、[(a+b)×c]×d 7、(a×b+c)×d 8、[a×(b+c)]×d 9、a÷(b+c+d) 10、a÷(b×c+d)
11、a÷[b×(c+d)] 12、a÷(b+c×d) 13、a÷[(b+c)×d] 14、a ○ b ○ c ○ d
1.1.4 实际python代码("# "后面的是注释部分):
from itertools import * #导入 itertools 模块,用于辅助排列组合时的操作
while True: #循环输入,防止输入不正确时直接结束
canbreak = [] #设置变量控制是否退出 while 循环
inputlist = input('24点游戏,请输入1~13中可以重复的四个整数,用一个空格隔开:').split(' ') #获取用户输入内容,并用空格分割四个数字,存储到列表中
for x in range(4):
if inputlist[x].isnumeric() == False: #如果输入的包含除数字以外内容,则重新输入
print('输入内容不正确!请重新输入')
print()
break
else:
if int(inputlist[x]) in [1,2,3,4,5,6,7,8,9,10,11,12,13]: #如果输入的数字在 1~13 之内,满足条件
inputlist[x] = int(inputlist[x])
if len(inputlist) == 4: #如果输入了4个数
canbreak.append(1) #满足条件,设置可以退出
else: #个数不正确
print('输入数字个数不正确!请重新输入')
print()
break
else:
print('输入数字大小不正确!请重新输入') #输入的数字不在 1~13 之内,则重新输入
print()
break
if len(canbreak) == 4 and not(0 in canbreak): #如果可以退出循环,则执行退出
break
def GameSolve(numlist): #定义函数,有一个参数,为一个包含四个数的列表
strfoption = ''
all_list = []
op_list = []
newlist1 = []
newlist2 = []
newlist3 = []
op_dict={1:'+',2:'-',3:'×',4:'÷'}
op_dict1={1:'+',2:'-',3:'*',4:'/'} #以上均为设置程序所需变量,和主要运算逻辑没有太大关系
for a in permutations(numlist,4): #将 numlist(输入的包含四个数的列表排列组合)
all_list.append([a[0],a[1],a[2],a[3]]) #把取出的四个数存储到列表中,这个列表用于存放四个数的所有排列方式
for x in range(1,5): #循环取出第1个运算符
for y in range(1,5): #循环取出第2个运算符
for z in range(1,5): #循环取出第3个运算符
op_list.append([x,y,z]) #将取出的三个运算符存储到列表中,这个列表用于存放三个运算符的所有排列方式
for num in all_list: #循环从四个数的所有排列方式中,取出一种排列方式
for option in op_list: #循环从三个运算符的所有排列方式中,取出一种排列方式
"""直接插入符号"""
show = str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3]) #直接插入符号,考虑优先级
if eval(show) == 24: #①如果直接插入符号时能算出24,则执行下面代码
strfoption = str(num[0])+op_dict[option[0]]+str(num[1])+op_dict[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3]) #把 "*" 替换为 "×","/" 替换为 "÷"
return strfoption #输出表达式,结束运算
else: #①的反面,即直接插入符号时不能算出24
"""插入包含2个数的括号"""
if (option[0] == 1 or option[0] == 2) and (option[1] == 3 or option[1] == 4): #如果第1个符号为 +/- ,第2个符号为 ×/÷,则需要考虑括号
show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+')'+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3]) #加入1个括号
if eval(show) == 24: #如果加上1个括号后能算出24,执行下面的代码
strfoption = '('+str(num[0])+op_dict[option[0]]+str(num[1])+')'+op_dict[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3]) #把 "*" 替换为 "×","/" 替换为 "÷"
return strfoption #输出表达式,结束运算
elif option[2] == 1 or option[2] == 2: #如果加上1个括号不能算出24,则再试试加上2个括号
show = '('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'
if eval(show) != 0 or option[1] != 4:
show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+')'+op_dict1[option[1]]+'('+str(num[2])+op_dict1[option[2]]+str(num[3])+')' #加入2个括号
if eval(show) == 24: #如果加上2个括号后能算出24,执行下面的代码
strfoption = '('+str(num[0])+op_dict[option[0]]&#