簡體   English   中英

類和對象:如何從方法中設置 boolean 以創建具有毒狀態的“機會”,或稍后用於閃避和其他可重復使用

[英]Classes and Objects: How do I set a boolean from a method to create "chance" with a poison status, or use later for dodge and other reusables

如何通過一種方法設置 boolean 以創建具有毒狀態的“機會”,或稍后用於閃避和其他可重復使用。

剛剛使用 Super() 學習簡單的 Inheritance,還沒有學習復雜的 Inheritance。不確定這是否會對我的編碼方式產生影響,但使用我所知道的,這就是我所擁有的。

我想做的是在英雄 Class 中創建一個方法,讓英雄只有在滿足條件或通過 boolean 時才會中毒。 我一直對邏輯有疑問。 還是編程新手。

我已經使用 Idle 多次重寫代碼以提高速度,但它一直給我帶來問題,即使我將 for 循環放在 hero.PoisionedCheck(True) 中,我也只得到顯示的文本,而沒有激活 forloop。 然后我會得到一個錯誤,“amount”參數在賦值之前沒有定義或調用,然后當我修復它時,我會得到 scorpion.health 和 scorpion.energy 沒有定義。 我在原地轉圈。

感謝您閱讀。

import time

class Monster:
    name= 'Monster'

    def __init__(self,health, energy):
        self.health = health
        self.energy = energy

    def attack(self, amount):
            print('Monster has attacked')
            print(f'{amount} damage was delt!')
            self.energy -= 20
        
    def move(self,speed):
            print(f'{self.name} has moved, at {speed} speed')

class Scorpion(Monster):
    
    name='Scorpion'
    def __init__(self,  health, energy):
        super().__init__(health, energy)
    
    def attack(self, amount):
        print('Scorpion has attacked')
        print('Poison has take effect!')
    
        # Loops Poison display repeated with time delay.
        # for repeater amount of times.
        repeater = 5
        for poison in range(repeater):
            poison = 0
            amount = poison + amount
            print(f'Poisoned: {amount} damage')
            time.sleep(0.5)
    
        poison = repeater
        amount *= poison
        print(f'Poison did a total damage of {amount} to {hero.name}')
        hero.health -= amount
        

class Hero(Monster):
    name = 'Rockwood'

    def __init__(self, health, energy) -> None:
        self.health = health
        self.energy = energy
    
    # How do I use this in a boolean to check Scorpion attack?
    # Lets say later adding *import random* later to determine chances of poison.
    # def PoisonedCheck(self, posioned):
    #     self.poisoned = posioned

    #     if posioned == True:
    #         print("Testing if become posioned- For loop goes after here to create damage.")
    #         posioned = True
        
    #     else:
    #         print('Became else.. ')
    #         posioned = False
        


monster = Monster(health=100, energy=100)
scorpion = Scorpion(health = 200, energy = 150)
hero = Hero(health=100, energy=100)

scorpion.attack(3)
print()

scorpion.move(110)
hero.move(50)
print(f"{hero.name} has {hero.health} health remaining. ")
print()

老實說,我不太確定您要實現什么目標,希望這能回答您的問題或幫助您前進。

首先,我建議為 Scorpion 的攻擊行為添加一個目標參數並修改它的行為。 這樣你就可以定義多個英雄並讓他們與蠍子作戰,例如:

scorpion = Scorpion(health = 200, energy = 150)
hero_one = Hero(health=100, energy=100)
hero_two = Hero(health=200, energy=100)

scorpion.attack(hero_one)
scorpion.attack(hero_two)

其次,蠍子攻擊后似乎不會失去能量,也不會造成初始傷害。 您可以通過將 Scorpion 攻擊行為更改為先調用父攻擊 function 來解決此問題:

class Scorpion(Monster):
...
    def attack(self, amount, target):
        super().attack(amount, target)
        print('Poison has take effect!')
        ...

但是怪物的攻擊行為不接受第二個參數,所以我的建議是用第二個參數修改怪物的攻擊 function 也對目標造成初始傷害(並正確地減去目標的生命值和傷害量):

class Monster:
...
    def attack(self, amount, target):
        print(f'{self.name} has attacked')
        print(f'{amount} damage was delt!')
        target.health -= amount
        self.energy -= 20

要跟蹤中毒狀態,最簡單的方法是在名為poisoned的 Monster class 構造函數中引入 state 並將其設置為False (初始 state 是怪物和每個子 object 未中毒)。

然后你可以在Scorpion的攻擊方法中改變目標中毒的state,像這樣:

class Scorpion(Monster):
...
    def attack(self, amount, target):
        ...
        target.poisoned = True
        ...

通過這種方式,您可以查看其中一位英雄是否中毒,如下所示:

  print(hero_one.poisoned) --> False or True (if attacked by scorpion)

要計算 Scorpion 的攻擊是否會使目標中毒的機會(比如說 50%),將毒應用行為提取到單獨的私有 function 中並像這樣修改它:

class Scorpion(Monster):
...
def attack(self, amount, target):
    super().attack(amount, target)
    self.__poison_target(amount, target)


def __poison_target(self, amount, target):
    # A coin toss to decide if target will be poisoned or not.
    should_apply_poison = random.randint(0, 1) == 1
    if should_apply_poison:
        print('Poison has take effect!')
        target.poisoned = True
        # Loops Poison display repeated with time delay.
        # for repeater amount of times.
        repeater = 5
        for poison in range(repeater):
            poison = 0
            amount = poison + amount
            print(f'Poisoned: {amount} damage')
            time.sleep(0.5)

        poison = repeater
        amount *= poison
        print(f'Poison did a total damage of {amount} to {target.name}')
        target.health -= amount
 ...

或者您可以通過創建抽象 class Poisonable將傷害處理行為從 Scorpion 委托給 Hero,您可以使用它來檢查目標是否有毒(在您的情況下 - Hero 繼承自Poisonable )。 這樣 Scorpion class 不關心目標是否成功中毒。

Poisonable class 是所有從它繼承的類都必須遵守的契約(例如,實現他們自己的抵抗版本,從毒葯中獲得傷害)。 這樣每個中毒的生物都會有不同的反應。

class Poison:
    def __init__(self):
        self.damage_per_tick = 5
        self.ticks = 3

class Scorpion(Monster):
    name = 'Scorpion'

    def __init__(self, health, energy):
        super().__init__(health, energy)
        self.poison = Poison()

    def attack(self, amount, target):
        super().attack(amount, target)
        self.__poison_target(target)


    def __poison_target(self, target):
        if isinstance(target, Poisonable):
            target.suffer_poison_damage(self.poison)


class Poisonable(ABC):
    @abc.abstractmethod
    def resist_poison(self) -> bool:
        pass

    @abc.abstractmethod
    def suffer_poison_damage(self, poison: Poison) -> None:
        pass

class Hero(Monster, Poisonable, ABC):
    name = 'Rockwood'

    def __init__(self, health, energy) -> None:
        super().__init__(health, energy)

    def resist_poison(self) -> bool:
        # resist poison chance
        return random.randint(0, 1) == 1

    def suffer_poison_damage(self, poison: Poison) -> None:
        if self.resist_poison():
            pass
        else:
            print('Poison has take effect!')
            # Loops Poison display repeated with time delay.
            # for repeater amount of times.
            total_amount = 0
            for poison_tick in range(poison.ticks):
                total_amount += poison.damage_per_tick
                print(f'Poisoned: {poison.damage_per_tick} damage')
                time.sleep(0.5)

            print(f'Poison did a total damage of {total_amount} to {self.name}')
            self.health -= total_amount

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM