Рефакторинг «ударить» значения для игры

1

Я делаю игру, и один из методов вычисляет числа попаданий базы персонажей на основе значений навыков. Метод в настоящее время вычисляет каждое значение индивидуально, так как каждое умение может использоваться на коротком, среднем и дальнем расстоянии.

Я изначально думал, что могу объединить навыки в кортеж и перебрать его, динамически создавая каждый номер хита. Но я не знаю, действительно ли это возможно, так как в настоящее время у каждого присваивается каждый номер, присвоенный ему собственной переменной.

Я также думал о создании метода для каждого диапазона и передаче кортежа в качестве аргумента. Я мог бы создать новый кортеж или список с результирующими значениями, а затем назначить их отдельным переменным, но я не вижу, как это будет лучше, чем делать это таким образом, за исключением того, что он не будет выглядеть так скопирован и вставлен.

Здесь у меня есть:

    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 делать это вручную, и я также хочу "будущий", если ситуация изменится в будущем.

Теги:
refactoring

5 ответов

6

Похоже, что вы действительно хотите, это класс, представляющий оружие, с атрибутами для обработки базовых значений и вычисления значений хита различными модификаторами. Вот простой пример:

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 для представления оружия, которое несет персонаж.

Все это довольно стандартная, скучная объектно-ориентированная процедура проектирования, но для множества ситуаций этот тип мышления быстро избавит вас от земли и обеспечит хотя бы небольшую базовую гибкость.

  • 0
    Если предварительный расчет так важен (хотя я действительно сомневаюсь в этом), он может использовать памятку по методам hit_value : code.activestate.com/recipes/52201
1

Давайте посмотрим, понимаю ли вы ваш сценарий: у каждого оружия есть свой собственный хит, так что у винтовки может быть 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
0

У меня будет класс для атрибутов символов (так что у вас нет кучи вещей в классе символов) и класса для атрибутов оружия:

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
0

Какое чувство динамики вы имеете в виду? Что может изменяться - количество навыков или весовые коэффициенты, количество диапазонов (короткий, средний, длинный) или все эти?

Что происходит с значениями (например,) bhPST_ * после этого - объединяются ли они в одно число?

Одна вещь, которая бросается в глаза, состоит в том, что список навыков жестко привязан к коду - я был бы склонен заменить переменные bh на метод

Итак (учтите, что я не знаю в первую очередь о Python:))

def bh_short(self, key)
  skill = self.skill_dict.get(key, 0)
  return skill * 0.6

Теперь вы можете сохранить список навыков, которые способствуют попаданию очков, и перебрать этот вызов bh_short и т.д.

Возможно также передать диапазон (длинный мед короткий) функции или вернуть все три значения - все это зависит от того, что вы собираетесь делать с расчетными точками hitpoint.

В принципе, нам нужна дополнительная информация о контексте, который будет использоваться в

0

@Vinko: возможно, сделайте calcBaseHitNumbers, выполните внутреннюю проверку "if not self.calculatedBase:" и просто не-op, если это было сделано раньше. Тем не менее, я не вижу насущной необходимости предусмотреть эту информацию. Но я не эксперт по производительности Python.

  • 0
    Я удалил свой ответ, так как Джеймс был лучше
  • 0
    Вы должны добавить это в качестве комментария, если вы не предложите ответ
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню