一、游戏玩法介绍:

24点游戏是儿时玩的主要益智类游戏之一,玩法为:从一副扑克中抽取4张牌,对4张牌使用加减乘除中的任何方法,使计算结果为24。例如,2,3,4,6,通过( ( ( 4 + 6 ) - 2 ) * 3 )  = 24,最快算出24者剩。

二、设计思路:

由于设计到了表达式,很自然的想到了是否可以使用表达式树来设计程序。本程序的确使用了表达式树,也是程序最关键的环节。简要概括为:先列出所有表达式的可能性,然后运用表达式树计算表达式的值。程序中大量的运用了递归,各个递归式不是很复杂,大家耐心看看,应该是能看懂的

表达式树:

表达式树的所有叶子节点均为操作数(operand),其他节点为运算符(operator)。由于本例中都是二元运算,所以表达式树是二叉树。下图就是一个表达式树

  

具体步骤:

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个非叶子节点。所以树的形状只有两种可能,就直接写死了

  

#树节点
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、输出结果

三、所有源码

  

#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])

经典趣味24点游戏程序设计(python)的更多相关文章

  1. 用python代替人脑运算24点游戏

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:老方玩编程 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...

  2. 《HTML5经典坦克大战》游戏(代码)

    前几天粗略地学了HTML5,然后就用它写了一个<经典坦克大战>游戏. 现在想分享一下我写的代码,写得不好请大家多多指教. 给大家推荐一个网站,这个网站是为大学生而做,为方便学习编程的同学而 ...

  3. php实现 24点游戏算法

    php实现 24点游戏算法 一.总结 一句话总结:把多元运算转化为两元运算,先从四个数中取出两个数进行运算,然后把运算结果和第三个数进行运算,再把结果与第四个数进行运算.在求表达式的过程中,最难处理的 ...

  4. cdoj 1252 24点游戏 dfs

    24点游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1252 Descr ...

  5. 24点游戏&&速算24点(dfs)

    24点游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  6. 24点游戏详细截图介绍以及原型、Alpha、Beta对比

    原型设计 图片展示 功能与界面设计 1.登录注册 2.手机号验证 3.24点游戏 4.粉色系女生界面 Alpha 图片展示 功能与界面设计 1.24点游戏 2.背景音乐 3.可查看多种可能的答案 4. ...

  7. 「JavaScript」手起刀落-一起来写经典的贪吃蛇游戏

    回味 小时候玩的经典贪吃蛇游戏我们印象仍然深刻,谋划了几天,小时候喜欢玩的游戏,长大了终于有能力把他做出来(从来都没有通关过,不知道自己写的程序,是不是能通关了...),好了,闲话不多谈,先来看一下效 ...

  8. C#俄罗斯方块小游戏程序设计与简单实现

    C#俄罗斯方块小游戏程序设计与简单实现 相信90后或者80后都玩过这款小游戏,一直想干一票,琢磨一下,但又不太懂,于是网上搜集修改就有了以下效果!bug较多,多多包涵! 1.效果展示 2.实现方法 参 ...

  9. 【Nodejs】“快算24”扑克牌游戏算法

    算24是一款扑克牌游戏,它的游戏方式是把四张牌的牌面数值通过四则运算得到结果24,四张牌必须仅用一次.这是一种挺好的锻炼孩子算数能力的扑克牌游戏. 各地玩法还有点差别,有的只算1-10,其它抽出来:有 ...

随机推荐

  1. swift网络编程入门应用:天气预报

    学习来自<小波说雨燕 第二季 网络编程(入门篇)> 工具:xcode6.4 首先在Main.storyborad中添加并设置好三个label做简单的界面显示: import UIKit / ...

  2. 快捷下载 sourceForge下的资源

    一些开源项目通常会放在  sourceforge.net下面发布.然而,这个网站有时候出现卡顿,并且需要点击几次页面才能下载到自己想要的资源. 这里有个好办法,一步列出所有可下载的资源:        ...

  3. debian7 请把标有“Debian GNU/Linux 7.1.0 _Wheezy_ - Official amd64 DVD Binary-1 20130615-23:06”的盘片插入驱动器“/media/cdrom/”再按回车键

    有时候,在通过apt-get install 安装软件的时候,会出现: 更换介质:请把标有“Debian GNU/Linux 7.1.0 _Wheezy_ - Official amd64 DVD B ...

  4. VS2010 单文档+多视图+Outlook风格

    先来个段子 十年生死两茫茫,喜羊羊,灰太狼.舒克贝塔,蓝猫话凄凉.纵使相逢应不识,圣斗士,美猴王.老夫聊发少年狂,治肾亏,不含糖.锦帽貂裘,千骑用康王.为报倾城随太守,三百年,九芝堂.夜来幽梦忽还乡, ...

  5. java微信接口之五—消息分组群发

    一.微信消息分组群发接口简介 1.请求:该请求是使用post提交地址为: https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_t ...

  6. Linux安装SmartSVN及破解

    转载自:linux 下svn图形客户端smartsvn 安装 一.准备         smartsvn需要java支持,首先请确认机器上有没有安装java 另外还请确认环境变量里有没有JAVA_HO ...

  7. python set集合简单使用

    Python 提供了强大的集合操作方法,我们可以完成数学中集合的并集.交集.差集等操作,如下: >>> a = {1,2,3} >>> b = {3,4,5} &g ...

  8. mysql存储过程procedure

    传送门 http://www.blogjava.net/sxyx2008/archive/2009/11/24/303497.html ) ); DROP PROCEDURE IF EXISTS ju ...

  9. Hive Word count

    --https://github.com/slimandslam/pig-hive-wordcount/blob/master/wordcount.hql DROP TABLE myinput; DR ...

  10. Java zip and unzip demo

    目录结构如下: import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import ...