一、游戏玩法介绍:
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])
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
python,24点
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]