在Python对象工厂中使用动态变量

时间:2014-03-18 18:42:43

标签: database python-2.7 eval factory

以下代码是一个片段,用于接收群集大小(遇到难度),玩家所处的游戏行为,以及玩家级别从数据库中选择敌人并创建它们。这提供了假设玩家处于行为1和等级1并使用为测试目的而编写的单一技能的测试案例。

EnemyDatabase={'1':{'1':{'Cultist':{'spawn':{'spawnrate':[0, 100], 'ClusterValue':2, 'EnemyLevelRange':(1, 3), 'HpPerLevel':20, 'XpPerLevel':2},
                                    'Fighter':{MaxHp:50, death_function:monster_death},
                                    'Skill':{'type' : 'low', 'TitanicOnslaught':(1, 1, .1, .2, 2)},
                                    'Corpse':{'DrainValue':None, 'XpValue':10, 'PreviouslyDrained':[False, False]},
                                    'AI':BasicMonster,
                                    'Object':{'name':'Cultist'}}}}}

SkillDatabase={'TitanicOnslaught':{'function':CastTitanicOnslaught, 'flags':['melee']}}

def GatherSpawnPool(PlayerLevel, EnemyDatabase):
    SpawnDict={}
    for key, value in EnemyDatabase[str(GameProgression.Act)]:
        if int(key)<=PlayerLevel:
            i=key
            for key, value in EnemyDatabase[str(GameProgression.Act)][i]:
                SpawnDict.update({key:value})
    return SpawnDict

def MobSelector(SpawnPool):
    #Select the enemies that will be spawned for this encounter from the spawn pool
    i=0
    EnemiesToSpawn=[]
    while i <= EncounterClusterSize:
        num=random.randrange(0.001, 100)
        for key in SpawnPool:
            if  num >= SpawnPool[key]['spawn']['spawnrate'][0] and num <= SpawnPool[key]['spawn']['spawnrate'][1]:
                EnemiesToSpawn.append(key)
                i+= SpawnPool[key]['spawn']['ClusterValue']
    return EnemiesToSpawn

def DynamicVariable(VarName, Value):
    return exec Varname+Value

def SkillFactory(SkillValues, SkillDatabase):
    if SkillValues['type']=='low':
        EntitySkills=[]
        for key, value in SkillValues:
            Flags=[]
            for x in SkillDatabase[key][flags]:
                Flags.append(exec x+"=True")
            EntitySkills.append(exec key+"=Skill(function=SkillDatabase[key]['function'], arguments=value, flags=Flags, **SkillValues['other'])")
        SkillStuff=LowActorSkill(AvailableSkills=EntitySkills, Cooldowns=[0 **len(EntitySkills)])
        return SkillStuff
        exec ""
    elif SkillValues['type']=='high':
        pass

def SpawnMobs(MobsToSpawn, SpawnPool, SkillDatabase):
    SpawnedEnemies=[]
    for enemy in MobsToSpawn:
        FighterComponent=Fighter(**SpawnPool[enemy]['Fighter'])
        CorpseComponent=Corpse(**SpawnPool[enemy]['Corpse'])
        SkillComponent=SkillFactory(SpawnPool[enemy]['Skill'], SkillDatabase)
        SpawnedEnemies.append(exec enemy + "=Object(ai=SpawnPool[enemy]['AI'], fighter=FighterComponent, corpse=CorpseComponent, skill=SkillComponent, **SpawnPool['enemy']['Object'])")
        return SpawnedEnemies

def MobFactory():
    global player, SkillDatabase, EnemyDatabase
    SpawnPool=GatherSpawnPool(player.level, EnemyDatabase)
    MobsToSpawn=MobSelector(SpawnPool)
    SpawnedMobs=SpawnMobs(MobsToSpawnl, SpawnPool, SkillDatabase)
    #FUNCTION TO PICK SPOTS FOR THE ENEMIES TO GO AND EDIT THEIR MAPX AND MAPY GOES HERE
    return SpawnedMobs

代码显然不起作用,因为我使用exec语句作为参数,但我无法提出解决方法。目标是从数据库中的所选敌人获得信息,以创建由字符串指示的技能对象。我知道动态命名变量通常是不好的做法,但它们永远不会被明确引用。游戏AI模块将覆盖实体轮流的所有可用能力(将只有25种可能性),并根据可用的操作运行适当的流程。我的问题是上面的代码如何将动态命名和创建的对象附加到列表?我确定此代码中还有其他一些小错误,但我真的无法测试那些直到我超越这一点。此外,我确信有很多方法可以加快或改进它,但是现在我正在使它成为工作的一部分&#34;让它发挥作用,使其正确,使之成为现实。快速&#34;

为了清晰起见,请随意编辑此问题,因为我不是最好的解释自己,并使其与社区更相关。

1 个答案:

答案 0 :(得分:0)

每当你开始思考“动态命名变量”时,请停下来思考“字典”。如果您不需要命名属性访问权限,那么列表通常也可以。例如,不是重复exec来创建每个Object,而是创建一个列表:

new_objects = []
for enemy in MobsToSpawn:
    ...
    new_objects.append(Object(ai=SpawnPool[enemy]['ai'], ...))

在其他地方,似乎应该使用字典:

for key, value in SkillValues.items(): # note .items()
    Flags={}
    for x in SkillDatabase[key][flags]: # where is flags from?
        Flags[x] = True