经典趣味24点游戏程序设计(python)
一、游戏玩法介绍:
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)的更多相关文章
- 用python代替人脑运算24点游戏
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:老方玩编程 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...
- 《HTML5经典坦克大战》游戏(代码)
前几天粗略地学了HTML5,然后就用它写了一个<经典坦克大战>游戏. 现在想分享一下我写的代码,写得不好请大家多多指教. 给大家推荐一个网站,这个网站是为大学生而做,为方便学习编程的同学而 ...
- php实现 24点游戏算法
php实现 24点游戏算法 一.总结 一句话总结:把多元运算转化为两元运算,先从四个数中取出两个数进行运算,然后把运算结果和第三个数进行运算,再把结果与第四个数进行运算.在求表达式的过程中,最难处理的 ...
- cdoj 1252 24点游戏 dfs
24点游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1252 Descr ...
- 24点游戏&&速算24点(dfs)
24点游戏 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- 24点游戏详细截图介绍以及原型、Alpha、Beta对比
原型设计 图片展示 功能与界面设计 1.登录注册 2.手机号验证 3.24点游戏 4.粉色系女生界面 Alpha 图片展示 功能与界面设计 1.24点游戏 2.背景音乐 3.可查看多种可能的答案 4. ...
- 「JavaScript」手起刀落-一起来写经典的贪吃蛇游戏
回味 小时候玩的经典贪吃蛇游戏我们印象仍然深刻,谋划了几天,小时候喜欢玩的游戏,长大了终于有能力把他做出来(从来都没有通关过,不知道自己写的程序,是不是能通关了...),好了,闲话不多谈,先来看一下效 ...
- C#俄罗斯方块小游戏程序设计与简单实现
C#俄罗斯方块小游戏程序设计与简单实现 相信90后或者80后都玩过这款小游戏,一直想干一票,琢磨一下,但又不太懂,于是网上搜集修改就有了以下效果!bug较多,多多包涵! 1.效果展示 2.实现方法 参 ...
- 【Nodejs】“快算24”扑克牌游戏算法
算24是一款扑克牌游戏,它的游戏方式是把四张牌的牌面数值通过四则运算得到结果24,四张牌必须仅用一次.这是一种挺好的锻炼孩子算数能力的扑克牌游戏. 各地玩法还有点差别,有的只算1-10,其它抽出来:有 ...
随机推荐
- PHPExcel中open_basedir restriction in effect的解决方法
用PHPExcel做导出execl的时候发现在本地没有问题,但是把网站传到租用的服务器的时候就报错,具体如下: Warning: realpath() [function.realpath]: ope ...
- sgu 104 Little shop of flowers 解题报告及测试数据
104. Little shop of flowers time limit per test: 0.25 sec. memory limit per test: 4096 KB 问题: 你想要将你的 ...
- Effective Java 06 Eliminate obsolete object references
NOTE Nulling out object references should be the exception rather than the norm. Another common sour ...
- redis客户端--jedis
一.jedis jedis 是 redis推荐的java客户端.通过Jedis我们可以很方便地使用java代码的方式,对redis进行操作.jedis使用起来比较简单,它的操作方法与redis命令相类 ...
- Ubuntu文本编辑时vi和nano命令的区别(建议使用nano)
vi是Unix世界里极为普遍的全荧幕文书编辑器,几乎可以说任何一台Unix机器都会提供这套软体就像windows的记事本一样. 键入 vi /etc/hosts 进入vi界面,把光标移动到文件未尾.按 ...
- hibernate多对多映射关系实现
Course.hbm.xml: <?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC &q ...
- 烂泥:KVM与kickstart集成
本文由秀依林枫提供友情赞助,首发于烂泥行天下. KVM与kickstart集成在这里我要说明下,因为在前面有关CentOS无人值守安装的文章中,我提到过如果要使用网卡PXE功能的话,内网中必须有DHC ...
- 烂泥:KVM快照的创建与恢复
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 因为要做有关KVM虚拟机的实验,所以需要虚拟机生成快照.查询相关资料,说KVM可以使用两种方法生成虚拟机的快照. 方法一.使用qemu-img snap ...
- LVS四种实现模式详解
一.集群cluster 当后端服务器承受不住访问的压力,提高服务器性能的解决方案会极大增加成本时,人们提出了横向扩展的解决方案.增加一台或几台服务器,提供相同的服务,通过前段分发器将访问量均匀的分配到 ...
- python 定时任务
Python 定时任务 最近学习到了 python 中两种开启定时任务的方法,和大家分享一下心得. sched.scheduler() threading.Timer() sched 定时任务 使用s ...