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 相关文章推荐
使用Pyrex来扩展和加速Python程序的教程
Apr 13 Python
Python isinstance函数介绍
Apr 14 Python
Python中动态检测编码chardet的使用教程
Jul 06 Python
Python基于回溯法子集树模板解决取物搭配问题实例
Sep 02 Python
浅谈Python Opencv中gamma变换的使用详解
Apr 02 Python
Python使用win32 COM实现Excel的写入与保存功能示例
May 03 Python
python调用百度地图WEB服务API获取地点对应坐标值
Jan 16 Python
Django上线部署之IIS的配置方法
Aug 22 Python
Python对Excel按列值筛选并拆分表格到多个文件的代码
Nov 05 Python
django rest framework 过滤时间操作
Jul 12 Python
Pythonic版二分查找实现过程原理解析
Aug 11 Python
聊聊Python中关于a=[[]]*3的反思
Jun 02 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
收听困难?教您超简便短波广播抗干扰方法!
2021/03/01 无线电
德生PL450的电路分析和低放电路的改进办法
2021/03/02 无线电
PHP将字符分解为多个字符串的方法
2014/11/22 PHP
php实现网站留言板功能
2015/11/04 PHP
PHP实现发送邮件的方法(基于简单邮件发送类)
2015/12/17 PHP
PHP实现微信模拟登陆并给用户发送消息的方法【文字,图片,图文】
2017/06/29 PHP
用tip解决Ext列宽度不够的问题
2008/12/13 Javascript
JavaScript toFixed() 方法
2010/04/15 Javascript
js iframe跨域访问(同主域/非同主域)分别深入介绍
2013/01/24 Javascript
JQuery给元素添加/删除节点比如select
2013/04/02 Javascript
javascript中的绑定与解绑函数应用示例
2013/06/24 Javascript
jQuery的$.proxy()应用示例介绍
2014/04/03 Javascript
一个简单的全屏图片上下打开显示网页效果示例
2014/07/08 Javascript
Jquery和JS获取ul中li标签的实现方法
2016/06/02 Javascript
利用JS实现简单的瀑布流加载图片效果
2017/04/22 Javascript
AngularJS+bootstrap实现动态选择商品功能示例
2017/05/17 Javascript
JavaScript实现的可变动态数字键盘控件方式实例代码
2017/07/15 Javascript
JavaScript hasOwnProperty() 函数实例详解
2017/08/04 Javascript
使用vue如何构建一个自动建站项目
2018/02/05 Javascript
webpack下实现动态引入文件方法
2018/02/22 Javascript
Auto.js自动收取自己和好友蚂蚁森林能量脚本
2018/06/28 Javascript
JavaScript引用类型Function实例详解
2018/08/09 Javascript
Node+OCR实现图像文字识别功能
2018/11/26 Javascript
微信小程序使用canvas自适应屏幕画海报并保存图片功能
2019/07/25 Javascript
javascript 对象 与 prototype 原型用法实例分析
2019/11/11 Javascript
Vue实现兄弟组件间的联动效果
2020/01/21 Javascript
用jQuery实现抽奖程序
2020/04/12 jQuery
原生JavaScript实现五子棋游戏
2020/11/09 Javascript
使用python实现扫描端口示例
2014/03/29 Python
python监控网卡流量并使用graphite绘图的示例
2014/04/27 Python
在Python中使用base64模块处理字符编码的教程
2015/04/28 Python
Python 爬虫模拟登陆知乎
2016/09/23 Python
Python urlopen()参数代码示例解析
2020/12/10 Python
四年大学生活的个人自我评价
2013/12/11 职场文书
《水上飞机》教学反思
2016/02/20 职场文书
SpringBoot整合minio快速入门教程(代码示例)
2022/04/03 Java/Android