Я делаю игру, и один из методов вычисляет числа попаданий базы персонажей на основе значений навыков. Метод в настоящее время вычисляет каждое значение индивидуально, так как каждое умение может использоваться на коротком, среднем и дальнем расстоянии.
Я изначально думал, что могу объединить навыки в кортеж и перебрать его, динамически создавая каждый номер хита. Но я не знаю, действительно ли это возможно, так как в настоящее время у каждого присваивается каждый номер, присвоенный ему собственной переменной.
Я также думал о создании метода для каждого диапазона и передаче кортежа в качестве аргумента. Я мог бы создать новый кортеж или список с результирующими значениями, а затем назначить их отдельным переменным, но я не вижу, как это будет лучше, чем делать это таким образом, за исключением того, что он не будет выглядеть так скопирован и вставлен.
Здесь у меня есть:
def calcBaseHitNumbers(self, dict):
"""Calculate character base hit numbers depending on skill level."""
self.skill_dict = dict
self.rifle = self.skill_dict.get('CRM', 0)
self.pistol = self.skill_dict.get('PST', 0)
self.big_gun = self.skill_dict.get('LCG', 0)
self.heavy_weapon = self.skill_dict.get('HW', 0)
self.bow = self.skill_dict.get('LB', 0)
#self.skill_tuple = (self.rifle, self.pistol, self.big_gun, self.heavy_weapon,
# self.bow)
#---Short range
## for skill in self.skill_tuple:
## self.base_hit_short = skill * 0.6
self.charAttribs.bhCRM_short = self.rifle * 0.6
self.charAttribs.bhPST_short = self.pistol * 0.6
self.charAttribs.bhHW_short = self.heavy_weapon * 0.6
self.charAttribs.bhLCG_short = self.big_gun * 0.6
self.charAttribs.bhLB_short = self.bow * 0.6
#---Med range
self.charAttribs.bhCRM_med = self.rifle * 0.3
self.charAttribs.bhPST_med = self.pistol * 0.3
self.charAttribs.bhHW_med = self.heavy_weapon * 0.3
self.charAttribs.bhLCG_med = self.big_gun * 0.3
self.charAttribs.bhLB_med = self.bow * 0.3
#---Long range
self.charAttribs.bhCRM_long = self.rifle * 0.1
self.charAttribs.bhPST_long = self.pistol * 0.1
self.charAttribs.bhHW_long = self.heavy_weapon * 0.1
self.charAttribs.bhLCG_long = self.big_gun * 0.1
self.charAttribs.bhLB_long = self.bow * 0.1
Как бы вы реорганизовали это, чтобы он стал более динамичным?
Изменить: Я предполагаю, что я хочу сделать следующее: Имейте кортеж (например, тот, который я прокомментировал), и повторяйте его 3 раза, каждый раз создавая новое значение (для каждого навыка) на основе модификатора для каждого конкретного диапазона. Полученное значение автоматически присваивается соответствующей переменной.
В моей голове это имеет смысл. Но когда я на самом деле пытаюсь закодировать его, я теряюсь. Проблема, я думаю, в том, что это первая "настоящая" программа, которую я написал; все, что я делал раньше, это небольшие скрипты.
Это только версия моей версии 0.1, поэтому сейчас не важно ее реорганизовать. Тем не менее, это кажется очень не-Pythonic делать это вручную, и я также хочу "будущий", если ситуация изменится в будущем.
Похоже, что вы действительно хотите, это класс, представляющий оружие, с атрибутами для обработки базовых значений и вычисления значений хита различными модификаторами. Вот простой пример:
SHORT_RANGE = 'S'
MEDIUM_RANGE = 'M'
LONG_RANGE = 'L'
SHORT_RANGE_MODIFIER = 0.6
MEDIUM_RANGE_MODIFIER = 0.3
LONG_RANGE_MODIFIER = 0.1
class Weapon(object):
def __init__(self, code_name, full_name, base_hit_value,
short_range_modifier=None, medium_range_modifier=None,
long_range_modifier=None):
self.code_name, self.full_name = code_name, full_name
self.base_hit_value = base_hit_value
self.range_modifiers = {
SHORT_RANGE: short_range_modifier or SHORT_RANGE_MODIFIER,
MEDIUM_RANGE: medium_range_modifier or MEDIUM_RANGE_MODIFIER,
LONG_RANGE: long_range_modifier or LONG_RANGE_MODIFIER,
}
def hit_value(self, range, modifier=1):
return self.base_hit_value * self.range_modifiers[range] * modifier
Оттуда вы можете создать экземпляры оружия внутри вашего объекта Character так:
self.rifle = Weapon('CRM', 'rifle', 5)
self.pistol = Weapon('PST', 'pistol', 10)
И если, скажем, персонаж стреляет из пистолета на короткое расстояние:
hit_value = self.pistol.hit_value(SHORT_RANGE)
Дополнительный аргумент метода hit_value() может использоваться для передачи изменений, характерных для конкретной ситуации или ситуации.
Разумеется, следующий шаг за этим будет заключаться в том, чтобы непосредственно моделировать оружие как подклассы Оружия (возможно, разбивать на конкретные типы оружия, такие как оружие, луки, гранаты и т.д., каждый со своими собственными базовыми значениями) и добавьте класс Inventory для представления оружия, которое несет персонаж.
Все это довольно стандартная, скучная объектно-ориентированная процедура проектирования, но для множества ситуаций этот тип мышления быстро избавит вас от земли и обеспечит хотя бы небольшую базовую гибкость.
Давайте посмотрим, понимаю ли вы ваш сценарий: у каждого оружия есть свой собственный хит, так что у винтовки может быть 1, тяжелое оружие может иметь 2 и т.д. Затем каждый символ имеет короткое, среднее и длинное значение, которое нужно умножить на точка удара оружия.
Вам следует рассмотреть возможность использования стратегии. Это создает суперкласс класса с хитом. Создайте оружие подкласса для винтовки, пистолета, лука и т.д. Я уверен, что различия между оружием больше, чем просто точки попадания.
Затем персонаж имеет одно или несколько видов оружия в зависимости от вашего игрового процесса. Чтобы вычислить точку попадания для определенного оружия, это просто, как
current_weapon * self.medium
Если вы решите добавить больше оружия позже, вам не придется редактировать код персонажа, потому что ваш персонаж может обрабатывать любое оружие.
В Pseudo Python
class Weapon
hit = 1
#other properties of weapon
class Rifle(Weapon)
#other properties of Rifle
class Pistol(Weapon)
#other properties of Pistol
class Character
weapon = Rifle()
long=0.6
def calcHit()
return self.long*weapon.hit
john = Character()
john.weapon= Rifle()
john.calcHit
У меня будет класс для атрибутов символов (так что у вас нет кучи вещей в классе символов) и класса для атрибутов оружия:
class WeaponAttribute(object):
short_mod = 0.6
med_mod = 0.3
long_mod = 0.1
def __init__(self, base):
self.base = base
@property
def short(self):
return self.base * self.short_mod
@property
def med(self):
return self.base * self.med_mod
@property
def long(self):
return self.base * self.long_mod
class CharacterAttributes(object):
def __init__(self, attributes):
for weapon, base in attributes.items():
setattr(self, weapon, WeaponAttribute(base))
Имейте объект CharacterAttributes
в классе символов и используйте его следующим образом:
# Initialise
self.charAttribs = CharacterAttributes(self.skill_dict)
# Get some values
print self.charAttribs.CRM.short
print self.charAttribs.PST.med
print self.charAttribs.LCG.long
Какое чувство динамики вы имеете в виду? Что может изменяться - количество навыков или весовые коэффициенты, количество диапазонов (короткий, средний, длинный) или все эти?
Что происходит с значениями (например,) bhPST_ * после этого - объединяются ли они в одно число?
Одна вещь, которая бросается в глаза, состоит в том, что список навыков жестко привязан к коду - я был бы склонен заменить переменные bh на метод
Итак (учтите, что я не знаю в первую очередь о Python:))
def bh_short(self, key)
skill = self.skill_dict.get(key, 0)
return skill * 0.6
Теперь вы можете сохранить список навыков, которые способствуют попаданию очков, и перебрать этот вызов bh_short и т.д.
Возможно также передать диапазон (длинный мед короткий) функции или вернуть все три значения - все это зависит от того, что вы собираетесь делать с расчетными точками hitpoint.
В принципе, нам нужна дополнительная информация о контексте, который будет использоваться в
@Vinko: возможно, сделайте calcBaseHitNumbers, выполните внутреннюю проверку "if not self.calculatedBase:" и просто не-op, если это было сделано раньше. Тем не менее, я не вижу насущной необходимости предусмотреть эту информацию. Но я не эксперт по производительности Python.