1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/python
# -*- coding: GBK -*-
#---------------------------------------------------------------------
#
#---------------------------------------------------------------------
##@package FormulaControl
# @todo: ¹«Ê½¹ÜÀíÆ÷
#
# @author: panwei
# @date 2010-09-01
# @version 1.0
#
# @note: ÓÃÓÚ»º´æÔ¤±à¼­µÄ¹«Ê½, Ìá¸ßevalµÄЧÂÊ
#---------------------------------------------------------------------
"""Version = 2010-09-01 16:40"""
#---------------------------------------------------------------------
#===============================================================================
# Áʽ¼ÆËãÌá¸ß25±¶µÄ·½·¨£º
# 1.Ô­·½·¨ 
# expression = "a + b"
# c = eval(expression)
# 2.ÏȱàÒ룬ºóeval
# expression = "a + b"
# d = compile(expression, "modeName", "eval")
# c = eval(d)
# ´óÁ¿ÔËËã²âÊÔ½á¹û£º
# c = eval(d) ±È
# c = eval(expression) ¿ì25±¶
# evalÒ»¸ö×Ö·û´®µÄʱ¼ä = ±àÒëÒ»¸ö×Ö·û´® + evalÒ»¸ö±àÒëºÃµÄÄ£¿é
#===============================================================================
#---------------------------------------------------------------------
 
import traceback
import random
import math
 
#---------------------------------------------------------------------
#¹«Ê½×ÖµäÃû×¢²á
#×¢²á¹«Ê½×ÖµäÃû·½Ê½ 'Facl_DistKey_ + KeyName' (ǰ׺ÃûÓÃÓÚÇø±ð²ß»®ÅäÖÃtxt¹«Ê½Key)
#ÀýÈç: Facl_DistKey_KillNPC = 'Facl_DistKey_KillNPC'
 
#---------------------------------------------------------------------
#»º´æ·þÎñÆ÷ËùÓеĹ«Ê½×ÖµäÐÅÏ¢{δ±àÒëµÄ¹«Ê½:±àÒëºóµÄ¹«Ê½}
AllFormulaDist = {}
 
#---------------------------------------------------------------------
##»ñÈ¡±àÒëºóµÄ¹«Ê½.
# @param formulaKey ×ÖµäKeyÃû
# @param noCompileFormula Î´±àÒëµÄ¹«Ê½
# @return ±àÒëºóµÄ¹«Ê½
# @remarks »ñÈ¡±àÒëºóµÄ¹«Ê½.
def GetCompileFormula(formulaKey, noCompileFormula):
    global AllFormulaDist
    
    compileFormula = AllFormulaDist.get(formulaKey)
    
    #---Õâ¸ö¹«Ê½ÒѾ­±àÒë¹ýÁË---
    if compileFormula != None:
        #GameWorld.Log('Õâ¸ö¹«Ê½ = %s ÒѾ­±àÒë¹ý, Ö±½Ó·µ»Ø'%(formulaKey))
        return compileFormula
    
    #---Õâ¸ö¹«Ê½Î´±àÒë¹ýÁË---
    compileFormula = compile(noCompileFormula, 'FormulaControl', 'eval')
    #¸üÐÂ×Öµä
    AllFormulaDist.update({formulaKey:compileFormula})
    #GameWorld.Log('Õâ¸ö¹«Ê½ = %s Î´±àÒë¹ý, ¼ÓÈë±àÒë'%(formulaKey))
    return compileFormula
#---------------------------------------------------------------------
##Çå¿Õ±àÒëºóµÄ¹«Ê½×Öµä
# @param ÎÞ²ÎÊý
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks Çå¿Õ±àÒëºóµÄ¹«Ê½×Öµä
def ClearCompileFormulaDist():
    global AllFormulaDist
    AllFormulaDist = {}
    #GameWorld.Log('ClearCompileFormulaDist Sucess AllFormulaDist = %s'%(AllFormulaDist))
    return
 
def Eval(formulaKey, formula, paramDict, toInt=True, ceil=False, playerID=0):
    """ ¶¯Ì¬¼ÆËã
    :param formulaKey: ¹«Ê½±àÒ뻺´ækey
    :param formula: ¹«Ê½×Ö·û´®£¬Èç "int(Atk*10 + MaxHP)"
    :param paramDict: ²ÎÊý×ֵ䣬Èç {'Atk': 100, 'MaxHP': 5000}
    :param toInt: ÊÇ·ñתΪÕûÊý
    :param ceil: ÊÇ·ñÏòÉÏÈ¡Õû
    :return: ¼ÆËã½á¹û
    """
    compileFormula = GetCompileFormula(formulaKey, formula)
    
    safe_env = {
        '__builtins__': None,
        # »ù´¡Êýѧº¯Êý
        'abs': abs,
        'min': min,
        'max': max,
        'pow': pow,
        'round': round,
        # ÀàÐÍת»»
        'int': int,
        'float': float,
        'bool': bool,
        # Êýѧ³£Êý
        #'pi': math.pi,
        #'e': math.e
    }
    safe_env.update(paramDict)
    try:
        # Ö´ÐмÆËã
        value = eval(compileFormula, safe_env)
        if ceil:
            value = math.ceil(value)
        if toInt:
            value = int(value)
        return value
    except:
        import GameWorld
        GameWorld.SendGameErrorEx("FormulaEvalError", "formulaKey:%s, %s, %s" % (formulaKey, paramDict, traceback.format_exc()), playerID)
        return 0
    
def test():
    attrParamDict={
    'lineupHaloPer': 0, 'awakeTalentPer': 0, 'breakLVPer': 0, 'breakLVValue': 0, 'bookValue': 0, 'lineupStarAddPer': 0, 'lvValue': 0, 
    'heroSelfValue': 0, 'awakeTalentValue': 0, 'fetterPer': 0, 'lineupBreakLVAddPer': 0, 
    'starTalentValue': 30, 'inheritPer': 1, 'equipValue': 269, 'fetterValue': 0, 'lineupLVAddPer': 0, 'heroSelfPer': 0, 
    'bookPer': 0, 'starTalentPer': 0, 'lineupHaloValue': 0, 'lineupInitAddPer': 0
    }
    
    formula = "(lvValue+equipValue+bookValue)*inheritPer+(heroSelfValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue"
    formula = "(lvValue+equipValue+bookValue)*(1+lineupHaloPer+bookPer+lineupInitAddPer+lineupLVAddPer+lineupBreakLVAddPer+lineupStarAddPer)*(inheritPer+fetterPer+starTalentValue+breakLVValue+awakeTalentValue)+heroSelfValue"
    
    import time
    doCount = 1
    
    time1 = time.time()
    for _ in xrange(doCount):
        value = Eval("aaa", formula, attrParamDict)
        print  "¹«Ê½ ¼ÆËã½á¹û: ", value
    print "use time %s" % (time.time() - time1)
    return
 
## Ê¹ÓÃʾÀý
#if __name__ == "__main__":
#    test()