找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 257|回复: 8

[求助] python写的计算24点游戏的小程序,请大侠们给点修改意见

1

主题

5

帖子

5

积分

贫民

积分
5
kill1000 发表于 2017-8-13 21:27:32 | 显示全部楼层 |阅读模式
python3写的计算24点游戏的小程序,基本上能算出来,但是我总觉得这个代码拖沓冗长,毫无美感。很久以前写过一点asp的程序,好多年没怎么写代码了。刚刚学了几天的python,感觉基础语法挺简单的,但是有些东西就很难理解,比如装饰器、生成器、函数式编程等等,所以写的这个24点程序的代码基本上还是沿用了以前asp的编程思想,python的特性还不太用的起来,不知道有没有哪位大侠可以指点一下,可以把这个小程序改的更python一点,或者说程序更漂亮一点,先谢过了!

以下是代码(不知道这样复制过来,格式上会不会有问题):
num={}      #定义一个字典,用来存放需要计算的数字
oper={1:'+',2:'-',3:'*',4:'/'}      #存放运算符的字典

#读入四个数字
for i in range(1,5):
    num=int(input('输入第'+str(i)+'个数:'))


l_num=[]    #用于存放4个数字不同的排列组合的列表
l_oper=[]   #用于存放运算符组合的列表
temp=[]     #临时列表

#生成4个数字的所有排列组合,数字不可重复使用
key_list=[0,0,0,0]
for i1 in range(1,5):
    key_list[0]=i1
    for i2 in range(1,5):
        if i2 not in key_list:
            key_list[1]=i2
        else:
            continue
        for i3 in range(1, 5):
            if i3 not in key_list:
                key_list[2]=i3
            else:
                continue
            for i4 in range(1, 5):
                if i4 not in key_list:
                    key_list[3]=i4
                    for n in key_list:
                        temp.append(num[n])
                    l_num.append(temp)
                    temp=[]
                    key_list[3] = 0
                else:
                    continue
            key_list[2] = 0
        key_list[1] = 0

#生成所有运算符的排列组合,运算符可以重复使用
key_list=[0,0,0]
temp=['','','']
for i1 in range(1,5):
    temp[0]=oper[i1]
    for i2 in range(1,5):
        temp[1] = oper[i2]
        for i3 in range(1, 5):
            temp[2] = oper[i3]
            l_oper.append(temp.copy())


#取出数字和运算符,进行组合
for nums in l_num:
    for opers in l_oper:
        s=[]
        #数字和运算符组合好之后还要考虑括号的情况,这里实在不知道怎么用循环来写,只好把括号的每一种情况都写出来
        s.append(str(nums[0])+opers[0]+str(nums[1])+ opers[1] + str(nums[2])+ opers[2] + str(nums[3]))
        s.append('('+str(nums[0])+opers[0]+str(nums[1])+')'+ opers[1] + str(nums[2])+ opers[2] + str(nums[3]))
        s.append('('+str(nums[0])+opers[0]+str(nums[1])+ opers[1] + str(nums[2])+')'+ opers[2] + str(nums[3]))
        s.append(str(nums[0])+opers[0]+'('+str(nums[1])+ opers[1] + str(nums[2])+')'+ opers[2] + str(nums[3]))
        s.append(str(nums[0])+opers[0]+'('+str(nums[1])+ opers[1] + str(nums[2])+ opers[2] + str(nums[3])+')')
        s.append(str(nums[0])+opers[0]+str(nums[1])+ opers[1] + '('+str(nums[2])+ opers[2] + str(nums[3])+')')

        #把最后生成的每一个表达式用eval来运算一下
        for ss in s:
#            print(ss)
            #分母为 0 时,不知道怎么处理,只要抓异常了
            try:
                value=eval(ss)
            except ZeroDivisionError:
                continue
            #考虑到除法运算会产生小数,所以最终取值在23.99 和 24.01之间
            if round(value,1)<=24.01 and round(value,1)>=23.99:
                print('算法:',ss)
                exit(0)
print('算不出来:(')


回复

使用道具 举报

0

主题

1

帖子

1

积分

贫民

积分
1
卢杰 发表于 2017-8-13 21:57:19 | 显示全部楼层
怎么运行之后报错了[img][/img]
回复 支持 反对

使用道具 举报

2

主题

382

帖子

382

积分

版主

Rank: 7Rank: 7Rank: 7

积分
382

最佳新人热心会员默默耕耘

whydo1 发表于 2017-8-13 23:59:01 | 显示全部楼层
  1. import itertools
  2. 待计算的数=[]
  3. 运算符=['+','-','*','/']

  4. 运算式=''
  5. 找到运算式=False
  6. 括号排列组合=[['(','','',')','','','',''],
  7.              ['(','','',')','(','','',')'],
  8.              ['','','','','(','','',')'],
  9.              ['','','(','','',')','',''],
  10.              ['(','','','','',')','',''],
  11.              ['((','','',')','',')','',''],
  12.              ['(','','(','','','))','',''],
  13.              ['','','(','','','','',')'],
  14.              ['','','((','','',')','',')'],
  15.              ['','','(','','(','','','))']]

  16. for i in range(1,5):
  17.     num=input('输入第'+str(i)+'个数:')
  18.     待计算的数.append(num)

  19. #生成算式
  20. 数字排列组合=list(itertools.permutations(待计算的数,4))
  21. 运算符排列组合=list(itertools.product(*[运算符]*3))
  22. for n in 数字排列组合:
  23.     for o in 运算符排列组合:
  24.         if '*' in o or '/' in o:
  25.             for ps in 括号排列组合:
  26.                 运算式=(ps[0]+n[0]+ps[1] +o[0] +
  27.                         ps[2]+n[1]+ps[3] +o[1] +
  28.                         ps[4]+n[2]+ps[5] +o[2] +
  29.                         ps[6]+n[3]+ps[7])
  30.         else:
  31.             运算式=n[0]+o[0]+n[1]+o[1]+n[2]+o[2]+n[3]
  32.             
  33.         try:
  34.             结果=eval(运算式)
  35.         except Exception as err:
  36.             pass
  37.         if 结果==24:
  38.             print(运算式)
  39.             找到运算式=True

  40. if 找到运算式:
  41.     pass
  42. else:
  43.     print('未找到运算式')
复制代码
python3.4.4, win10
回复 支持 反对

使用道具 举报

1

主题

5

帖子

5

积分

贫民

积分
5
kill1000  楼主| 发表于 2017-8-14 11:02:31 | 显示全部楼层
卢杰 发表于 2017-8-13 21:57
怎么运行之后报错了[/img]

代码复制过来,有些东西被自动改掉了,可能这个论坛上有些限制,应该要像版主那样复制代码才可以
回复 支持 反对

使用道具 举报

1

主题

5

帖子

5

积分

贫民

积分
5
kill1000  楼主| 发表于 2017-8-14 11:20:56 | 显示全部楼层
重新发一遍试试看:
  1. num={}      #定义一个字典,用来存放需要计算的数字
  2. oper={1:'+',2:'-',3:'*',4:'/'}      #存放运算符的字典

  3. #读入四个数字
  4. for i in range(1,5):
  5.     num[i]=int(input('输入第'+str(i)+'个数:'))


  6. l_num=[]    #用于存放4个数字不同的排列组合的列表
  7. l_oper=[]   #用于存放运算符组合的列表
  8. temp=[]     #临时列表

  9. #生成4个数字的所有排列组合,数字不可重复使用
  10. key_list=[0,0,0,0]
  11. for i1 in range(1,5):
  12.     key_list[0]=i1
  13.     for i2 in range(1,5):
  14.         if i2 not in key_list:
  15.             key_list[1]=i2
  16.         else:
  17.             continue
  18.         for i3 in range(1, 5):
  19.             if i3 not in key_list:
  20.                 key_list[2]=i3
  21.             else:
  22.                 continue
  23.             for i4 in range(1, 5):
  24.                 if i4 not in key_list:
  25.                     key_list[3]=i4
  26.                     for n in key_list:
  27.                         temp.append(num[n])
  28.                     l_num.append(temp)
  29.                     temp=[]
  30.                     key_list[3] = 0
  31.                 else:
  32.                     continue
  33.             key_list[2] = 0
  34.         key_list[1] = 0

  35. #生成所有运算符的排列组合,运算符可以重复使用
  36. key_list=[0,0,0]
  37. temp=['','','']
  38. for i1 in range(1,5):
  39.     temp[0]=oper[i1]
  40.     for i2 in range(1,5):
  41.         temp[1] = oper[i2]
  42.         for i3 in range(1, 5):
  43.             temp[2] = oper[i3]
  44.             l_oper.append(temp.copy())


  45. #取出数字和运算符,进行组合
  46. for nums in l_num:
  47.     for opers in l_oper:
  48.         s=[]
  49.         #数字和运算符组合好之后还要考虑括号的情况,这里实在不知道怎么用循环来写,只好把括号的每一种情况都写出来
  50.         s.append(str(nums[0])+opers[0]+str(nums[1])+ opers[1] + str(nums[2])+ opers[2] + str(nums[3]))
  51.         s.append('('+str(nums[0])+opers[0]+str(nums[1])+')'+ opers[1] + str(nums[2])+ opers[2] + str(nums[3]))
  52.         s.append('('+str(nums[0])+opers[0]+str(nums[1])+ opers[1] + str(nums[2])+')'+ opers[2] + str(nums[3]))
  53.         s.append(str(nums[0])+opers[0]+'('+str(nums[1])+ opers[1] + str(nums[2])+')'+ opers[2] + str(nums[3]))
  54.         s.append(str(nums[0])+opers[0]+'('+str(nums[1])+ opers[1] + str(nums[2])+ opers[2] + str(nums[3])+')')
  55.         s.append(str(nums[0])+opers[0]+str(nums[1])+ opers[1] + '('+str(nums[2])+ opers[2] + str(nums[3])+')')

  56.         #把最后生成的每一个表达式用eval来运算一下
  57.         for ss in s:
  58. #            print(ss)
  59.             #分母为 0 时,不知道怎么处理,只要抓异常了
  60.             try:
  61.                 value=eval(ss)
  62.             except ZeroDivisionError:
  63.                 continue
  64.             #考虑到除法运算会产生小数,所以最终取值在23.99 和 24.01之间
  65.             if round(value,1)<=24.01 and round(value,1)>=23.99:
  66.                 print('算法:',ss)
  67.                 exit(0)
  68. print('算不出来:(')
复制代码
回复 支持 反对

使用道具 举报

1

主题

5

帖子

5

积分

贫民

积分
5
kill1000  楼主| 发表于 2017-8-14 11:33:08 | 显示全部楼层

itertools.permutations  这个库好帅,我在这个地方花了好长时间想怎么做,结果这有现成的
回复 支持 反对

使用道具 举报

1

主题

5

帖子

5

积分

贫民

积分
5
kill1000  楼主| 发表于 2017-8-14 11:41:51 | 显示全部楼层

但是这个程序好像还有点问题,有时候用除法算的,算到最后会有一个小数,比如  3,3,8,8这四个数字,可以用8/(3-8/3)  这个算法,但是电脑直接算的话有个小数,你的程序会认为这个算法是错的。为了满足这种情况,我把最终的计算结果在在23.99 和 24.01之间都算是对的,但是这个方法总感觉太别扭,不知道有没有更好的办法?
回复 支持 反对

使用道具 举报

2

主题

382

帖子

382

积分

版主

Rank: 7Rank: 7Rank: 7

积分
382

最佳新人热心会员默默耕耘

whydo1 发表于 2017-8-15 10:42:43 | 显示全部楼层
如果考虑分数的话. 可以用Fraction
from fractions import Fraction
python3.4.4, win10
回复 支持 反对

使用道具 举报

0

主题

23

帖子

23

积分

贫民

积分
23
剑心无痕 发表于 2017-9-7 15:25:36 | 显示全部楼层
https://github.com/gaoziqi/24-Points
四则运算不可计算: 458组
七则运算不可计算: 126组
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表