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之入门(四)运算
May 27 Python
python使用装饰器和线程限制函数执行时间的方法
Apr 18 Python
Python输出PowerPoint(ppt)文件中全部文字信息的方法
Apr 28 Python
Python爬虫框架Scrapy基本用法入门教程
Jul 26 Python
django框架事务处理小结【ORM 事务及raw sql,customize sql 事务处理】
Jun 27 Python
详解DeBug Python神级工具PySnooper
Jul 03 Python
python使用pandas处理excel文件转为csv文件的方法示例
Jul 18 Python
Python之数据序列化(json、pickle、shelve)详解
Aug 30 Python
解决torch.autograd.backward中的参数问题
Jan 07 Python
Python版中国省市经纬度
Feb 11 Python
解决json中ensure_ascii=False的问题
Apr 03 Python
Python 的 f-string 可以连接字符串与数字的原因解析
Feb 20 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
PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
2014/08/18 PHP
关于Laravel参数验证的一些疑与惑
2019/11/19 PHP
JavaScript 函数调用规则
2009/09/14 Javascript
jquery parent和parents的区别分析
2013/10/02 Javascript
JavaScript实现添加及删除事件的方法小结
2015/08/04 Javascript
基于javascript实现全屏漂浮广告
2016/03/31 Javascript
JavaScript实现图片懒加载(Lazyload)
2016/11/28 Javascript
Javascript仿京东放大镜的效果
2017/03/01 Javascript
微信小程序自定义组件实现tabs选项卡功能
2018/07/14 Javascript
浅谈Fetch 数据交互方式
2018/12/20 Javascript
js prototype和__proto__的关系是什么
2019/08/23 Javascript
javascript异常处理实现原理详解
2020/02/17 Javascript
在vue-cli创建的项目中使用sass操作
2020/08/10 Javascript
vue将data恢复到初始状态 && 重新渲染组件实例
2020/09/04 Javascript
[40:48]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第二局
2016/02/28 DOTA
Python3基础之输入和输出实例分析
2014/08/18 Python
Python最长公共子串算法实例
2015/03/07 Python
Python同步遍历多个列表的示例
2019/02/19 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
Python unittest 自动识别并执行测试用例方式
2020/03/09 Python
keras读取训练好的模型参数并把参数赋值给其它模型详解
2020/06/15 Python
python Cartopy的基础使用详解
2020/11/01 Python
详解Html5 监听拦截Android返回键方法
2018/04/18 HTML / CSS
美国中西部家用医疗设备商店:Med Mart(轮椅、踏板车、升降机等)
2019/04/26 全球购物
C语言50道问题
2014/10/23 面试题
银行柜员应聘推荐信范文
2013/11/24 职场文书
党校学习自我鉴定
2014/02/24 职场文书
团队经理竞聘书
2014/03/31 职场文书
法制宣传标语
2014/06/23 职场文书
医德医魂心得体会
2014/09/11 职场文书
2015年平安创建工作总结
2015/04/29 职场文书
小学运动会通讯稿
2015/07/18 职场文书
python基础入门之字典和集合
2021/06/13 Python
解析探秘fescar分布式事务实现原理
2022/02/28 Java/Android
《战锤40K:暗潮》跳票至9月 公布新宣传片
2022/04/03 其他游戏
win10电脑关机快捷键是哪个 win10快速关机的几种方法
2022/08/14 数码科技