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基于smtplib实现异步发送邮件服务
May 28 Python
Python的time模块中的常用方法整理
Jun 18 Python
详解Python安装scrapy的正确姿势
Jun 26 Python
virtualenv 指定 python 解释器的版本方法
Oct 25 Python
对Python3 pyc 文件的使用详解
Feb 16 Python
python下PyGame的下载与安装过程及遇到问题
Aug 04 Python
简单了解Python3 bytes和str类型的区别和联系
Dec 19 Python
python 装饰器功能与用法案例详解
Mar 06 Python
解决Jupyter notebook更换主题工具栏被隐藏及添加目录生成插件问题
Apr 20 Python
python 获取字典特定值对应的键的实现
Sep 29 Python
python实现数据结构中双向循环链表操作的示例
Oct 09 Python
教你漂亮打印Pandas DataFrames和Series
May 29 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引用效率问题分析
2012/03/23 PHP
Laravel 4.2 中队列服务(queue)使用感受
2014/10/30 PHP
jQuery Mobile + PHP实现文件上传
2014/12/12 PHP
解决PhpStorm64不能启动的问题
2020/06/20 PHP
JavaScript数组常用方法
2015/03/02 Javascript
jquery判断复选框选中状态以及区分attr和prop
2015/12/18 Javascript
JavaScript中的函数(二)
2015/12/23 Javascript
从重置input file标签中看jQuery的 .val() 和 .attr(“value”) 区别
2016/06/12 Javascript
require.js配合插件text.js实现最简单的单页应用程序
2016/07/12 Javascript
jQuery EasyUI API 中文帮助文档和扩展实例
2016/08/01 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
2016/10/26 Javascript
vuejs router history 配置到iis的方法
2018/09/20 Javascript
VUE 自定义组件模板的方法详解
2019/08/30 Javascript
在vue中配置不同的代理同时访问不同的后台操作
2020/09/11 Javascript
python重试装饰器示例
2014/02/11 Python
python基于pygame实现响应游戏中事件的方法(附源码)
2015/11/11 Python
python 删除大文件中的某一行(最有效率的方法)
2017/08/19 Python
Python读取excel中的图片完美解决方法
2018/07/27 Python
numpy添加新的维度:newaxis的方法
2018/08/02 Python
python清除字符串前后空格函数的方法
2018/10/21 Python
浅谈python之高阶函数和匿名函数
2019/03/21 Python
numpy数组之存取文件的实现示例
2019/05/24 Python
Python-copy()与deepcopy()区别详解
2019/07/12 Python
基于梯度爆炸的解决方法:clip gradient
2020/02/04 Python
解决python Jupyter不能导入外部包问题
2020/04/15 Python
Python基于pillow库实现生成图片水印
2020/09/14 Python
印度和世界各地的精美产品:Ikka Dukka
2018/02/12 全球购物
澳大利亚当地最大的时装生产商:Cue
2018/08/06 全球购物
施华洛世奇西班牙官网:SWAROVSKI西班牙
2019/06/06 全球购物
营销主管自我评价怎么写
2013/09/19 职场文书
卫生巾广告词
2014/03/18 职场文书
2014年房地产销售工作总结
2014/12/01 职场文书
2015年暑假生活总结
2015/07/13 职场文书
退休教师欢送会致辞
2015/07/31 职场文书
pytest配置文件pytest.ini的详细使用
2021/04/17 Python
PHP面试题 wakeup魔法 Ezpop pop序列化与反序列化
2022/04/11 PHP