经典趣味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])

时间: 2024-10-08 23:02:14

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

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

前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:老方玩编程 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http://t.cn/A6Zvjdun 24点是一个老少皆宜的智力游戏.从一幅扑克牌中随机抽出4张,把这4张牌作为4个数字,参加游戏的人用这4个数字和基本的小学算术运算,使得计算的结果等于24.谁先算出来谁就赢得了游戏. 算24的游戏,对编程来说是一个不小的挑战.一般来说,需要通过某种方

通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数--菜单功能'menufile

通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数--菜单功能'menufile 1 #猜数字--核心代码--猜测次数--随机函数和屏蔽错误代码---优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数--菜单功能'menufile' 2 #!usr/bin/env python 3 #-*-c

24点游戏的算法实现

根据要求实现一个24点的游戏算法,要求如下: 输入:n1,n2,m1,m2 如果这个四个数的运算结果是24,则输出运算表达式 如11,8,3,5 输出:(11-8)*(3*5)=24 解法一:蛮力法,遍历所有的表达式组合,首先遍历所有的数字的排列组合,然后遍历运算符的组合,然后计算出 这个表达式的值,看其是否等于24 测试输入: 5,5,5,1 3,3,7,73,3,8,81,4,5,6 3,8,8,10 4,,410,10 9,9,6,2 11,8,3,5 #---*--- encoding=

[华为机试练习题]44.24点游戏算法

题目 注意: 6 + 2 * 4 + 10 = 24 不是一个数字一个数字的计算 代码 /*--------------------------------------- * 日期:2015-07-03 * 作者:SJF0115 * 题目:24点游戏算法 * 来源:华为机试练习题 -----------------------------------------*/ #include <iostream> #include <string> #include <vector&

24点游戏

题目描述 给出4个正整数操作数,你的任务是使用运算符(+,-,*,/)和括号对操作数进行计算,分析是否能得到24,每个操作数只能使用1次,运算符和括号可以多次使用,注意所有的中间结果都是整数. 输入 输入包括多行,每行4个正整数,范围是[1,13],输入以0 0 0 0标记结束 输出 若输入的4个操作数能计算出24,输出Yes,否则输出No 样例输入 1 1 1 1 2 5 7 8 0 0 0 0 样例输出 No Yes #include<iostream>   #include<str

微信公众平台开发—24点游戏

一.源码 package org.xs.dntown.wx.game24.modules.web; import java.text.NumberFormat; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Random; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager

24点游戏(dfs)

24点游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 2424点就是给你一串数字,问你是否通过加减乘除括号构成2424点. 沈爷觉得这个很好玩,就决定考考你,给你44个数,可以交换位置,可以用加减乘除和括号,是否能构成2424点呢? 注意哦~这里的除法并不是整数除法,比如样例 Input 第一行TT,表示有多少组测试数据,1≤T≤501≤T≤5

cdoj 1252 24点游戏 dfs

24点游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1252 Description 24点就是给你一串数字,问你是否通过加减乘除括号构成24点. 沈爷觉得这个很好玩,就决定考考你,给你4个数,可以交换位置,可以用加减乘除和括号,是否能构成24点呢? 注意哦~这里的除法并不是整数除法,比如样例 Input 第一行T,表示有多少组测试数据,1≤T≤50 接下来T行,每行4

24点游戏计算器 (简单四则运算)(c++)

24点游戏计算器 (简单四则运算)(c++):https://github.com/liuxinig/cpp_1001/blob/master/24dian_siZeIN.txt 1 //24点统计 2 3 #include <iostream> 4 #include <cmath> 5 using namespace std; 6 #define N 14 7 //a数组存四个数字 8 int cixu[3],fuHao[3],p[N],sum = 0; 9 float a0[4