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 sort、sorted高级排序技巧
Nov 21 Python
Python3生成手写体数字方法
Jan 30 Python
python中ASCII码和字符的转换方法
Jul 09 Python
Python之两种模式的生产者消费者模型详解
Oct 26 Python
详解Python读取yaml文件多层菜单
Mar 23 Python
在Python中构建增广矩阵的实现方法
Jul 01 Python
python基于FTP实现文件传输相关功能代码实例
Sep 28 Python
python元组的概念知识点
Nov 19 Python
Pytorch Tensor的统计属性实例讲解
Dec 30 Python
python 链接sqlserver 写接口实例
Mar 11 Python
Python必须了解的35个关键词
Jul 16 Python
Python 读取位于包中的数据文件
Aug 07 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
解析Extjs与php数据交互(增删查改)
2013/06/25 PHP
PHP实现负载均衡的加权轮询方法分析
2018/08/22 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
2019/12/20 PHP
Prototype使用指南之string.js
2007/01/10 Javascript
关于文本框的一些限制控制总结~~
2010/04/15 Javascript
精心挑选的15款优秀jQuery 本特效插件和教程
2012/08/06 Javascript
jquery中each方法示例和常用选择器
2014/07/08 Javascript
常用jQuery选择器总结
2014/07/11 Javascript
javascript 构造函数方式定义对象
2015/01/02 Javascript
js+css实现tab菜单切换效果的方法
2015/01/20 Javascript
Javascript 6里的4个新语法
2016/08/25 Javascript
浅谈jquery中next与siblings的区别
2016/10/27 Javascript
JavaScript基于Dom操作实现查找、修改HTML元素的内容及属性的方法
2017/01/20 Javascript
使用vue.js实现checkbox的全选和多个的删除功能
2017/02/17 Javascript
jquery实现tab选项卡切换效果(悬停、下方横线动画位移)
2017/05/05 jQuery
react-router中的属性详解
2017/06/01 Javascript
vue动态路由实现多级嵌套面包屑的思路与方法
2017/08/16 Javascript
Three.js利用orbit controls插件(轨道控制)控制模型交互动作详解
2017/09/25 Javascript
js正则表达式校验指定字符串的方法
2018/07/23 Javascript
微信小程序之swiper滑动面板用法示例
2018/12/04 Javascript
详解Vue、element-ui、axios实现省市区三级联动
2019/05/07 Javascript
es6中new.target的作用和使用场景简单示例分析
2020/03/14 Javascript
使用Typescript和ES模块发布Node模块的方法
2020/05/25 Javascript
Vue封装Axios请求和拦截器的步骤
2020/09/16 Javascript
python判断字符串是否是json格式方法分享
2017/11/07 Python
Python开启线程,在函数中开线程的实例
2019/02/22 Python
python numpy生成等差数列、等比数列的实例
2020/02/25 Python
pandas分批读取大数据集教程
2020/06/06 Python
Python 按比例获取样本数据或执行任务的实现代码
2020/12/03 Python
移动web模拟客户端实现多方框输入密码效果【附代码】
2016/03/25 HTML / CSS
农药学硕士毕业生自荐信
2013/09/25 职场文书
专升本自我鉴定
2013/10/10 职场文书
留学顾问岗位职责
2014/04/14 职场文书
共筑中国梦演讲稿
2014/04/23 职场文书
Python调用腾讯API实现人脸身份证比对功能
2022/04/04 Python
Python 匹配文本并在其上一行追加文本
2022/05/11 Python