python经典趣味24点游戏程序设计


Posted in Python onJuly 26, 2019

一、游戏玩法介绍:

24点游戏是儿时玩的主要益智类游戏之一,玩法为:从一副扑克中抽取4张牌,对4张牌使用加减乘除中的任何方法,使计算结果为24。例如,2,3,4,6,通过( ( ( 4 + 6 ) - 2 ) * 3 ) = 24,最快算出24者剩。

二、设计思路:

由于设计到了表达式,很自然的想到了是否可以使用表达式树来设计程序。本程序的确使用了表达式树,也是程序最关键的环节。简要概括为:先列出所有表达式的可能性,然后运用表达式树计算表达式的值。程序中大量的运用了递归,各个递归式不是很复杂,大家耐心看看,应该是能看懂的

表达式树:

表达式树的所有叶子节点均为操作数(operand),其他节点为运算符(operator)。由于本例中都是二元运算,所以表达式树是二叉树。下图就是一个表达式树

python经典趣味24点游戏程序设计

具体步骤:

1、遍历所有表达式的可能情况

遍历分为两部分,一部分遍历出操作数的所有可能,然后是运算符的所有可能。全排列的计算采用了递归的思想

#返回一个列表的全排列的列表集合
def list_result(l):
  if len(l) == 1:
    return [l]
  all_result = []
  for index,item in enumerate(l):
    r = list_result(l[0:index] + l[index+1:])
    map(lambda x : x.append(item),r)
    all_result.extend(r)
  return all_result

2、根据传入的表达式的值,构造表达式树

由于表达式树的特点,所有操作数均为叶子节点,操作符为非叶子节点,而一个表达式(例如( ( ( 6 + 4 ) - 2 ) * 3 ) = 24) 只有3个运算符,即一颗表达式树只有3个非叶子节点。所以树的形状只有两种可能,就直接写死了

python经典趣味24点游戏程序设计 

python经典趣味24点游戏程序设计

#树节点
class Node:

  def __init__(self, val):
    self.val = val
    self.left = None
    self.right = None
def one_expression_tree(operators, operands):
  root_node = Node(operators[0])
  operator1 = Node(operators[1])
  operator2 = Node(operators[2])
  operand0 = Node(operands[0])
  operand1 = Node(operands[1])
  operand2 = Node(operands[2])
  operand3 = Node(operands[3])
  root_node.left = operator1
  root_node.right =operand0
  operator1.left = operator2
  operator1.right = operand1
  operator2.left = operand2
  operator2.right = operand3
  return root_node

def two_expression_tree(operators, operands):
  root_node = Node(operators[0])
  operator1 = Node(operators[1])
  operator2 = Node(operators[2])
  operand0 = Node(operands[0])
  operand1 = Node(operands[1])
  operand2 = Node(operands[2])
  operand3 = Node(operands[3])
  root_node.left = operator1
  root_node.right =operator2
  operator1.left = operand0
  operator1.right = operand1
  operator2.left = operand2
  operator2.right = operand3
  return root_node

3、计算表达式树的值

也运用了递归

#根据两个数和一个符号,计算值
def cal(a, b, operator):
  return operator == '+' and float(a) + float(b) or operator == '-' and float(a) - float(b) or operator == '*' and float(a) * float(b) or operator == '÷' and float(a)/float(b)

def cal_tree(node):
  if node.left is None:
    return node.val
  return cal(cal_tree(node.left), cal_tree(node.right), node.val)

4、输出所有可能的表达式

还是运用了递归

def print_expression_tree(root):
  print_node(root)
  print ' = 24'

def print_node(node):
  if node is None :
    return
  if node.left is None and node.right is None:
    print node.val,
  else:
    print '(',
    print_node(node.left)
    print node.val,
    print_node(node.right)
    print ')',
    #print ' ( %s %s %s ) ' % (print_node(node.left), node.val, print_node(node.right)),

5、输出结果

python经典趣味24点游戏程序设计

三、所有源码

#coding:utf-8
from __future__ import division

from Node import Node


def calculate(nums):
  nums_possible = list_result(nums)
  operators_possible = list_result(['+','-','*','÷'])
  goods_noods = []
  for nums in nums_possible:
    for op in operators_possible:
      node = one_expression_tree(op, nums)
      if cal_tree(node) == 24:
        goods_noods.append(node)
      node = two_expression_tree(op, nums)
      if cal_tree(node) == 24:
        goods_noods.append(node)
  map(lambda node: print_expression_tree(node), goods_noods)




def cal_tree(node):
  if node.left is None:
    return node.val
  return cal(cal_tree(node.left), cal_tree(node.right), node.val)


#根据两个数和一个符号,计算值
def cal(a, b, operator):
  return operator == '+' and float(a) + float(b) or operator == '-' and float(a) - float(b) or operator == '*' and float(a) * float(b) or operator == '÷' and float(a)/float(b)

def one_expression_tree(operators, operands):
  root_node = Node(operators[0])
  operator1 = Node(operators[1])
  operator2 = Node(operators[2])
  operand0 = Node(operands[0])
  operand1 = Node(operands[1])
  operand2 = Node(operands[2])
  operand3 = Node(operands[3])
  root_node.left = operator1
  root_node.right =operand0
  operator1.left = operator2
  operator1.right = operand1
  operator2.left = operand2
  operator2.right = operand3
  return root_node

def two_expression_tree(operators, operands):
  root_node = Node(operators[0])
  operator1 = Node(operators[1])
  operator2 = Node(operators[2])
  operand0 = Node(operands[0])
  operand1 = Node(operands[1])
  operand2 = Node(operands[2])
  operand3 = Node(operands[3])
  root_node.left = operator1
  root_node.right =operator2
  operator1.left = operand0
  operator1.right = operand1
  operator2.left = operand2
  operator2.right = operand3
  return root_node

#返回一个列表的全排列的列表集合
def list_result(l):
  if len(l) == 1:
    return [l]
  all_result = []
  for index,item in enumerate(l):
    r = list_result(l[0:index] + l[index+1:])
    map(lambda x : x.append(item),r)
    all_result.extend(r)
  return all_result

def print_expression_tree(root):
  print_node(root)
  print ' = 24'

def print_node(node):
  if node is None :
    return
  if node.left is None and node.right is None:
    print node.val,
  else:
    print '(',
    print_node(node.left)
    print node.val,
    print_node(node.right)
    print ')',

if __name__ == '__main__':
  calculate([2,3,4,6])

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python在linux中输出带颜色的文字的方法
Jun 19 Python
Python中的getopt函数使用详解
Jul 28 Python
Python编程之序列操作实例详解
Jul 22 Python
在python win系统下 打开TXT文件的实例
Apr 29 Python
python 集合 并集、交集 Series list set 转换的实例
May 29 Python
用python中的matplotlib绘制方程图像代码
Nov 21 Python
解决Pycharm 导入其他文件夹源码的2种方法
Feb 12 Python
Python os模块常用方法和属性总结
Feb 20 Python
pycharm 如何取消连按两下shift出现的全局搜索
Jan 15 Python
虚拟环境及venv和virtualenv的区别说明
Feb 05 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
Mar 03 Python
pycharm debug 断点调试心得分享
Apr 16 Python
对django后台admin下拉框进行过滤的实例
Jul 26 #Python
python函数的万能参数传参详解
Jul 26 #Python
Python企业编码生成系统之主程序模块设计详解
Jul 26 #Python
Django REST Framework序列化外键获取外键的值方法
Jul 26 #Python
django admin.py 外键,反向查询的实例
Jul 26 #Python
Python企业编码生成系统之系统主要函数设计详解
Jul 26 #Python
python的re模块使用方法详解
Jul 26 #Python
You might like
星际玩家的三大定律
2020/03/04 星际争霸
新手配置 PHP 调试环境(IIS+PHP+MYSQL)
2007/01/10 PHP
PHP生成excel时单元格内换行问题的解决方法
2010/08/26 PHP
PHP程序员不应该忽略的3点
2015/10/09 PHP
PHP+Mysql+jQuery中国地图区域数据统计实例讲解
2015/10/10 PHP
thinkPHP自定义类实现方法详解
2016/11/30 PHP
AngularJS入门教程之Hello World!
2014/12/06 Javascript
node.js中的fs.chown方法使用说明
2014/12/16 Javascript
jQuery操作动态生成的内容的方法
2016/05/28 Javascript
前端框架Vue.js构建大型应用浅析
2016/09/12 Javascript
让编辑器支持word复制黏贴、截屏的js代码
2016/10/17 Javascript
Vue 让元素抖动/摆动起来的实现代码
2018/05/31 Javascript
微信小程序 生成携带参数的二维码
2019/10/23 Javascript
[28:48]《真视界》- 2017年国际邀请赛
2017/09/27 DOTA
python实现文件分组复制到不同目录的例子
2014/06/04 Python
在类Unix系统上开始Python3编程入门
2015/08/20 Python
python 表达式和语句及for、while循环练习实例
2017/07/07 Python
python中sys.argv函数精简概括
2018/07/08 Python
对tf.reduce_sum tensorflow维度上的操作详解
2018/07/26 Python
简单了解python PEP的一些知识
2019/07/13 Python
详解Python3 pickle模块用法
2019/09/16 Python
python读取dicom图像示例(SimpleITK和dicom包实现)
2020/01/16 Python
python实现可下载音乐的音乐播放器
2020/02/25 Python
Python模拟登录和登录跳转的参考示例
2020/10/30 Python
CSS3中引入多种自定义字体font-face
2020/06/12 HTML / CSS
美国时尚女装在线:Missguided
2016/12/03 全球购物
金牌葡萄酒俱乐部:Gold Medal Wine Club
2017/11/02 全球购物
抽象类和接口的区别
2012/09/19 面试题
95%的面试官都会问到的50道Java线程题,附答案
2012/08/03 面试题
毕业生个人的自我评价优秀范文
2013/10/03 职场文书
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
化工专业求职信
2014/07/01 职场文书
2014超市收银员工作总结
2014/11/13 职场文书
2015年全国爱耳日活动总结
2015/02/27 职场文书
2015年全国保险公众宣传日活动方案
2015/05/06 职场文书
一篇文章带你搞懂Python类的相关知识
2021/05/20 Python