Обновление свойств объекта в ООП Python

#python #oop

#python #ооп

Вопрос:

Я пытаюсь создать простую игру на Python, используя стиль ООП. Родительский класс настроен, и в нем есть два подкласса: один для героя и один для орка.

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

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

 class Character:
    '''Blueprint for game characters'''
    def __init__(self):
        #default values
        self.character = ""
        self.speed = 0
        self.power = 0
        self.health = 100

    def attack(self, attackObj):
        self.attacker = self.character
        self.attackerPower = self.power
        self.victim = attackObj.character
        self.victimHealth = attackObj.health
        self.newHealth = self.victimHealth - self.attackerPower
        print(self.character, "you have chosen to attack", self.victim)
        print(self.victim, "you have suffered", self.attackerPower, "damage and     your health is now", self.newHealth)


class Hero(Character):
    '''Inherits from character to create hero'''
    def __init__(self):
        Character.__init__(self)
        self.character = "Hero"
        self.speed = 8
        self.power = 9
        print(self.character, "you have",self.speed, "speed,", self.power, "power and", self.health, "health.")


class Ork(Character):
    '''Inherits from character to create ork'''
    def __init__(self):
        Character.__init__(self)
        self.character = "Ork"
        self.speed = 2
        self.power = 8
        print(self.character, "you have",self.speed, "speed,", self.power,     "power and", self.health, "health.")

def main():
    charclass = Character()
    hero = Hero()
    ork = Ork()

    endLoop = False
    while endLoop == False:
        print("Please choose your character by typing the corresponding key: ")
        print("H for hero")
        print("O for ork")
        charChoice = input()
        if charChoice in ("H", "h", "hero", "Hero"):
            charChoice = hero
            enemy = ork
            hero = Hero()

        elif charChoice in ("O", "o", "ork", "Ork"):
            charChoice = ork
            enemy = hero

        print("Please choose an action by typing the corresponding key: ")
        print("A to attack")
        actionChoice = input()
        if actionChoice in ("A", "a"):
            charChoice.attack(enemy)  
        else:
            print("Nothing chosen!")

        finishedYN = input("Have you finished? Y/N ")
        if finishedYN in ("Y", "y", "Yes", "yes", "YES"):
            print("You have chosen to end the game...")
            endloop = True
            break
        else:
            pass

if __name__ == "__main__":
    main()
 

Комментарии:

1. Я не запускал ваш код, но похоже, что вы создаете новый Hero объект на каждой итерации цикла : hero = Hero() .

2. Кроме того, почему вы это делаете: self.victimHealth = attackObj.health ? Вы просто добавляете self ко всему в своем классе?

3. Я только что удалил эту строку (должно быть, это был пережиток прошлого), но это никак не влияет на остальную часть программы. Он по-прежнему просто возвращается к оригиналу. Мне нужен какой-то способ отправить свойство power злоумышленника жертве и вычесть это из работоспособности, а затем каким-то образом запомнить это на следующей итерации. Как я уже сказал, я мог бы сделать это грязным и процедурным способом, но хотел бы, чтобы кто-нибудь подсказал мне правильный способ ООП для этого.

4. Вы никогда не изменяете health атрибут, просто создаете новый вызываемый атрибут newHealth . Вы также никогда не влияете на attackObject health атрибут ‘s.

5. Да, я только что добавил self ко всему. Эта строка должна была получить доступ к атрибуту мощности злоумышленника и вычесть его из состояния здоровья жертвы. Ранее у меня была строка кода, которая была примерно такой: newHealth = self.attackerPower — self.victimHealth затем я пытался получить к нему доступ и заставить его обновить соответствующий класс, но это просто не сработало. Я перепробовал много вариантов, прежде чем спрашивать здесь.

Ответ №1:

Быстрое исправление вашего кода. Удалите все эти ненужные атрибуты, например self.attacker (это просто self ), self.attackPower (это просто self.power ). self.victim = attackObj.character просто дает вашему объекту новый атрибут, который является той же строкой, что и все, что attackObj.character есть. Аналогично, это: self.newHealth = self.victimHealth - self.attackerPower просто создает новый атрибут при каждом вызове метода, который всегда будет равен 100 — self.attack

 def attack(self, attackObj):
    attackObj.health -= self.power
    print(self.character, "you have chosen to attack", attackObj.character)
    print(attackObj.character, "you have suffered", self.power, "damage and     your health is now", attackObj.health)
 

На самом деле, еще лучший способ — добавить методы, которые изменяют ваш объект, которые будут использоваться в качестве интерфейса с тем, как ваш объект взаимодействует с другими объектами. Так, например:

 class Character:
    '''Blueprint for game characters'''
    def __init__(self):
        #default values
        self.character = ""
        self.speed = 0
        self.power = 0
        self.health = 100

    def attack(self, victim):
        victim.receive_damage(self.power)

    def receive_damage(raw_damage):
        self.health -= raw_damage
 

Это улучшает расширяемость вашего кода. Вы могли бы более легко реализовать систему «баффов» или добавить элемент «брони», который влияет на то, как вы получаете урон, без необходимости изменять код attack . Вы можете переопределить эти методы в подклассах. Итак, возможно, вы хотите, чтобы у всех орков была «толстая кожа», а в Ork :

     def receive_damage(raw_damage):
        self.health -= raw_damage*self.thickskin_modifier
 

Где self.thickskin_modifier было задано в Ork классе __init__ . Это может быть что-то вроде 0.9.

Комментарии:

1. Хорошо, я посмотрю, поиграю и немного отвечу с окончательным рабочим кодом (надеюсь).

2. Эй, это работает! Спасибо за это. Я новичок в ООП, и я не могу выразить вам, как я благодарен за помощь.