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 相关文章推荐
Python3实现从指定路径查找文件的方法
May 22 Python
Python MySQL数据库连接池组件pymysqlpool详解
Jul 07 Python
python+selenium开发环境搭建图文教程
Aug 11 Python
Python学习笔记之if语句的使用示例
Oct 23 Python
Python实现的多项式拟合功能示例【基于matplotlib】
May 15 Python
利用Python将每日一句定时推送至微信的实现方法
Aug 13 Python
python读写配置文件操作示例
Jul 03 Python
python pycharm最新版本激活码(永久有效)附python安装教程
Sep 18 Python
tensorflow求导和梯度计算实例
Jan 23 Python
Numpy中ndim、shape、dtype、astype的用法详解
Jun 14 Python
五分钟学会怎么用Pygame做一个简单的贪吃蛇
Jan 06 Python
Python爬虫设置Cookie解决网站拦截并爬取蚂蚁短租的问题
Feb 22 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/07/17 PHP
laravel 5 实现模板主题功能(续)
2015/03/02 PHP
thinkPHP使用pclzip打包备份mysql数据库的方法
2016/04/30 PHP
PHP模拟http请求的方法详解
2016/11/09 PHP
详解Yaf框架PHPUnit集成测试方法
2017/12/27 PHP
基于laravel where的高级使用方法
2019/10/10 PHP
js打印纸函数代码(递归)
2010/06/18 Javascript
根据出生日期自动取得星座的js代码
2010/07/20 Javascript
JQuery操作Select的Options的Bug(IE8兼容性视图模式)
2013/04/21 Javascript
js控制网页背景音乐播放与停止的方法
2015/02/06 Javascript
JavaScript中setUTCMilliseconds()方法的使用详解
2015/06/12 Javascript
js漂浮广告实现代码
2015/08/15 Javascript
JS返回只包含数字类型的数组实例分析
2016/12/16 Javascript
layui导航栏实现代码
2017/05/19 Javascript
详解在vue-cli项目中使用mockjs(请求数据删除数据)
2017/10/23 Javascript
Vuex 进阶之模块化组织详解
2018/01/12 Javascript
浅谈微信小程序flex布局基础
2018/09/10 Javascript
学习jQuery中的noConflict()用法
2018/09/28 jQuery
微信小程序实现Swiper轮播图效果
2019/11/22 Javascript
Element InputNumber计数器的使用方法
2020/07/27 Javascript
Javascript柯里化实现原理及作用解析
2020/10/22 Javascript
[04:11]2014DOTA2国际邀请赛 CIS遗憾出局梦想不灭
2014/07/09 DOTA
Python后台管理员管理前台会员信息的讲解
2019/01/28 Python
使用python socket分发大文件的实现方法
2019/07/08 Python
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
GNC健安喜美国官网:美国第一营养品牌
2016/07/22 全球购物
会话Bean的种类
2013/11/07 面试题
自我评价优秀范文分享
2013/11/30 职场文书
小学生安全保证书
2014/02/01 职场文书
家长写给老师的建议书
2014/03/13 职场文书
优秀家长事迹材料
2014/05/17 职场文书
企业职业病防治方案
2014/05/29 职场文书
施工安全标语
2014/06/07 职场文书
单位工作证明
2014/10/07 职场文书
2015年环境监察工作总结
2015/07/23 职场文书
Android实现图片九宫格
2022/06/28 Java/Android