我制作了一个程序,它将在暗黑破坏神3中经历至少1,016,064个齿轮排列。我一直在尝试不同的理论实现,我决定使用类来表示每个排列而不是不得不处理庞大而复杂的词典。使用这种方法,我可以存储一个实例,然后在新的排列优于前者时替换它。
在任何情况下,我的计算机(i7-3632QM)需要大约40秒才能完成所有排列,每次排列只需要30个翻牌,我甚至无法想象如果它必须定义需要多长时间每次实例化一个类时,所有50个方法。无论如何,这就是我认为的样子:
class perm:
def __init__(self, *args):
self.x = 10
self.y = 5
self.z = 100
for item in args:
if hasattr(self, item):
getattr(self, item)()
self.val_1 = self.x * 2
self.val_2 = self.y * 5
self.val_3 = self.z/(self.z+300)
def head_1(self):
self.x += 5
self.z + 200
def head_2(self):
self.x += 10
self.y += 10
def feet_1(self):
self.y += 5
self.z += 250
def feet_2(self):
self.x += 10
self.z += 500
current_best = perm('head_1','feet_2')
答案 0 :(得分:3)
似乎正确的方法是为您拥有的每个齿轮选项创建对象,然后使用函数计算所有齿轮选项。
import itertools
class Gear(object):
def __init__(self, *args, **kwargs):
# I have no idea what Gear should do...
class Headpiece(Gear):
...
class Legs(Gear):
...
# etc
def calculate_perm(gear_tuple):
result = do_some_calculation_over(gear_tuple)
return result
best = max(itertools.permutations(all_your_gear), key=calculate_perm)
您甚至可以创建一个类似于perm
的类,但我会给它一个更具描述性的名称:
class EquipmentSet(object):
slots = ['head', 'legs', ... ]
def __init__(self, head=None, legs=None, ...)
self.head = head
self.legs = legs
...
self.equipment = [getattr(self, item) for item in self.slots]
@property
def x(self)
return sum(item.x for item in self.equipment)
# similar for y and z
@property
def val_1(self):
return self.x * 2
# similar for val_2, val_3
# implement dunder rich comparison methods?
result = max(EquipmentSet(*gearset) for \
gearset in itertools.permutations(all_your_gear))
答案 1 :(得分:1)
字符串就是一个例子。这些列表应该包含Gear
类,这些实例知道什么类型的“奖励”装置。
import itertools
headpieces = ['headpiece1', 'headpiece2', 'headpiece3']
armors = ['armor1', 'armor2']
weapons = ['weapon1', 'weapon2']
print list(itertools.product(headpieces, armors, weapons))
# result:
[('headpiece1', 'armor1', 'weapon1'),
('headpiece1', 'armor1', 'weapon2'),
('headpiece1', 'armor2', 'weapon1'),
('headpiece1', 'armor2', 'weapon2'),
('headpiece2', 'armor1', 'weapon1'),
('headpiece2', 'armor1', 'weapon2'),
('headpiece2', 'armor2', 'weapon1'),
('headpiece2', 'armor2', 'weapon2'),
('headpiece3', 'armor1', 'weapon1'),
('headpiece3', 'armor1', 'weapon2'),
('headpiece3', 'armor2', 'weapon1'),
('headpiece3', 'armor2', 'weapon2')]
此代码以 lazy 方式为您提供所有可能的齿轮(不将其传递给list()
它返回生成器),优化(itertools
在C中实现),因为优雅。请注意,在每个元素中只有一个头饰/武器/盔甲。可以推广到额外的齿轮。
之后你只需编写某种聚合器,它可以输入输入并返回'得分'。
答案 2 :(得分:0)
嗯,我决定使用itertools,一个我没有经验的模块(但在此之后会发生变化!),而且我已经让一半的脚本进行了测试。虽然我不是最有效的方式,但我也可以完成它,尽管我可以接受建议......
import time, itertools
class Barb:
def __init__(_, args):
_.elements = ['arcane','cold','fire','lightning','poison','physical']
_.strength = 5460 # max ancient str
_.vitality = 140
_.armor = 10188
_.all_res = 250
_.resistances = {element:7.7 for element in _.elements}
_.dodge = 0
_.armor_bonus_percent = .25
_.all_res_bonus_percent = 0
_.life_bonus_percent = .25
_.elemental_damage_reduction = 1
_.regen = 10730
_.life_on_hit = 8035
_.life_per_fury_spent = 0
_.life_percent_per_second_regen = 0
_.damage_mod = 1
_.cc = .05
_.cd = 2.8
_.ias = .25
_.attacks_per_second = 1.69
_.ww_damage_percent = 0
_.dibs = 0
_.cdr = 1
_.elemental_damage_bonus = .2
_.bastions = False
# apply gear bonuses
for arg in args:
getattr(_, arg)()
def helm_1(_):
_.cc += .06
_.ww_damage_percent += .15
_.life_bonus_percent += .23
_.resistances['arcane'] += 210
def helm_2(_):
_.cc += .06
_.vitality += 1000
_.life_bonus_percent += .23
_.resistances['arcane'] += 210
def torso_1(_):
_.vitality += 650
_.life_bonus_percent += .15
_.resistances['fire'] += 210
def torso_2(_):
_.all_res += 120
_.vitality += 650
def pants_1(_):
_.vitality += 650
_.armor += 700
_.resistances['physical'] += 210
def pants_2(_):
_.vitality += 650
_.all_res += 120
def bastions_1(_):#ring set
_.strength += 1000
_.cc += .12
_.cd += 1
_.resistances['physical'] += 210
_.resistances['poison'] += 210
_.bastions = True
def bastions_2(_):
_.strength += 500
_.cc += .12
_.cd += 1
_.cdr *= .92
_.resistances['physical'] += 210
_.resistances['poison'] += 210
_.bastions = True
def bk_1(_): # (str, dmg, cdr) + (str, cdr, vit)
_.strength += 2000
_.damage_mod *= 1.05
_.cdr *= .9 * .9
_.vitality += 1000
def bk_2(_): # (str, dmg, cdr) + (str, dmg, loh)
_.strength += 2000
_.damage_mod *= 1.1
_.cdr *= .9
_.life_on_hit += 18000
def best_score():
def available_items(prefix):
#automagically check barb for possible item variants of the item slot 'prefix'
# so more can be added at a later time
r = []
i = 1
while True:
name = '%s_%s'%(prefix, i)
if hasattr(Barb, name):
r.append(name)
else: return r
i += 1
gear_slots = [
'helm','torso','pants','bastions','bk']
helms, torso, pants, bastions, bk = [available_items(i) for i in gear_slots]
gears = itertools.product(helms, torso, pants, bastions, bk)
bestOffense = {'gear':[],
'health':0,
'mitigation':0,
'damage':0}
elapsed = time.time()
while True:
try:
args = next(gears)
barb = Barb(args)
armor = barb.armor * (1 + barb.armor_bonus_percent)
damage_reduction = armor / (armor + 3500)
resistances = {res:(barb.resistances[res] + barb.all_res) \
* (1 + barb.all_res_bonus_percent) for \
res in barb.resistances}
elemental_dr = {res:resistances[res]/(resistances[res] + 350) \
for res in resistances}
health = barb.vitality * 100 * (1 + barb.life_bonus_percent)
aps = barb.attacks_per_second * (1 + barb.ias)
damage_mod = barb.damage_mod * (1 + (barb.strength / 100))
damage_mod *= (1 - barb.cc) + (barb.cc * barb.cd)
damage_mod *= 2.25 if barb.bastions else 1
damage_mod *= 1 + barb.elemental_damage_bonus
dust_devils = 25 * damage_mod * (1 + barb.dibs + barb.ww_damage_percent)
min_elemental_dr = elemental_dr[min(elemental_dr)]
mitigation = 1 - ((1-damage_reduction) * (1-min_elemental_dr))
if dust_devils > bestOffense['damage']:
bestOffense = {'gear':args,
'health':health,
'mitigation':mitigation,
'damage':dust_devils}
except: return bestOffense, time.time() - elapsed
答案 3 :(得分:-2)
Python static methods将阻止解释器在内存中为每个类的实例创建一个新函数。您只能将其用于不需要操作实例的功能,即不使用{
"livescore": {
"league": [
{
"match": {
"home": {
"_goals": "2",
"_id": "2337787",
"_name": "Defensa y Justicia"
},
"away": {
"_goals": "3",
"_id": "2337780",
"_name": "Colon Santa FE"
},
"events": {
"event": [
{
"_assist": "",
"_assistid": "",
"_extra_min": "",
"_id": "22295244",
"_minute": "22",
"_player": "J. Tejera",
"_playerid": "2405930",
"_result": "",
"_team": "home",
"_type": "yellowcard"
}
]
},
"ht": {
"_score": "[1-1]"
},
"ft": {
"_score": "[2-3]"
},
"_alternate_id": "4100536",
"_alternate_id_2": "4328174",
"_commentary": "True",
"_date": "12.05.2015",
"_id": "4218094",
"_static_id": "12051523377872337780",
"_status": "FT",
"_time": "00:10"
},
"_country": "argentina",
"_name": "Argentina: Primera Division",
"_cup": "False",
"_id": "2914",
"_sub_id": "29144"
},
{
"match": [
{
"home": {
"_goals": "?",
"_id": "2337758",
"_name": "Berazategui"
},
"away": {
"_goals": "?",
"_id": "2337826",
"_name": "General Lamadrid"
},
"events": "",
"ht": {
"_score": ""
},
"_alternate_id": "4106986",
"_alternate_id_2": "4328905",
"_commentary": "False",
"_date": "12.05.2015",
"_id": "4224541",
"_static_id": "12051523377582337826",
"_status": "18:00",
"_time": "18:00"
},
{
"home": {
"_goals": "?",
"_id": "2337842",
"_name": "Justo José de Urquiza"
},
"away": {
"_goals": "?",
"_id": "2337850",
"_name": "Laferrere"
},
"events": "",
"ht": {
"_score": ""
},
"_alternate_id": "4106988",
"_alternate_id_2": "4329005",
"_commentary": "False",
"_date": "12.05.2015",
"_id": "4224543",
"_static_id": "12051523378422337850",
"_status": "18:00",
"_time": "18:00"
}
],
"_country": "argentina",
"_name": "Argentina: Primera C Metropolitana",
"_cup": "False",
"_id": "2912",
"_sub_id": "29120"
}
],
"_updated": "12.05.2015 06:41:07",
"_sport": "soccer"
}
}
的功能。