【问题标题】:How to use inheritance to level up a character如何使用继承来升级角色
【发布时间】:2021-03-30 03:42:40
【问题描述】:
# Import Modules
from Dice import dice
d10 = dice(10,1) #I use dice, but you could just as easily use random.randint()
d4 = dice(4,1)
d20 = dice(20,1)

# Assign Classes
class Player_Character:
    inventory = []
    def __init__(self, HP, MaxHP, AC, ToHitAdjustment, Surprise_Adjustment, 
                 Initiative_Adjustment, Exp, \
                 MaxExp, Gold, Damage):
        self.HP = int(HP)
        self.MaxHP = int(MaxHP)
        self.AC = int(AC)
        self.ToHitAdjustment = int(ToHitAdjustment)
        self.Surprise_Adjustment = int(Surprise_Adjustment)
        self.Initiative_Adjustment = int(Initiative_Adjustment)
        self.Exp = int(Exp)
        self.MaxExp = int(MaxExp)
        self.Gold = int(Gold)
        self.Damage = int(Damage)

下一部分可能是错误所在,尽管我对此表示怀疑,因为当我运行代码时,字符被分配了 exp 和 gold,它们似乎以正确的速度增长。

    def attack(self, goblin, Player_Character):
        Player_attack_roll = d20.die_roll() + Player_Character.ToHitAdjustment
        if (Player_attack_roll >= goblin.AC):
            print('you did', Player_Character.Damage, 'damage')
            goblin.HP -= Player_Character.Damage
            if (goblin.HP <= 0):
                print("congratulations you killed the goblin")
                Player_Character.Exp += goblin.ExpReward
                if (Player_Character.Exp >= Player_Character.MaxExp):
                    print("Congratulations you have leveled up")
                    Player_Character.LevelUp()
                print('you have', Player_Character.Exp, 'exp ')
                Player_Character.Gold += goblin.Gold
                print("you have", Player_Character.Gold, 'gold ')
                del goblin
        else:
            print("You miss ")

    def flee(self):
        print("you run away ")
        quit()

    def heal(self, Player_Character):
        Player_Character.HP += d10.die_roll()
        if Player_Character.HP >= Player_Character.MaxHP:
            Player_Character.HP = Player_Character.MaxHP
            print("You have reached max HP ")

这可能是错误所在,我希望它将先前分配给 Player_Character 的变量名称“MrHezy”分配给 FighterLvl1,但是当我运行代码时,它不断说我正在升级,我不确定如果这意味着角色仍然是 Player_Character,或者还有其他错误

    def LevelUp(self):
        MrHezy = FighterLvl1(25, 25, 15, 10, 2, 2, 25, 75, 20, d10.die_roll()+5)

下一部分的代码是我的继承问题发挥作用的地方。尽管 FighterLvl1 继承自 (Player_Character),但我的 IDE 说“FighterLvl1 的未解析属性引用‘Exp’”我也不确定在 FighterLvl1 下添加“攻击”方法是否有任何作用;我希望它会覆盖 Player_Character 中的“攻击”方法

class FighterLvl1(Player_Character):
    def attack(self, goblin, Player_Character):
        Player_attack_roll = d20.die_roll() + Player_Character.ToHitAdjustment
        if (Player_attack_roll >= goblin.AC):
            print('you did', Player_Character.Damage, 'damage')
            goblin.HP -= Player_Character.Damage
            if (goblin.HP <= 0):
                print("congratulations you killed the goblin")
                FighterLvl1.Exp += goblin.ExpReward
                if (FighterLvl1.Exp >= FighterLvl1.MaxExp):
                    print("Congratulations you have leveled up")
                    FighterLvl1.LevelUp()
                print('you have', FighterLvl1.Exp, 'exp ')
                FighterLvl1.Gold += goblin.Gold
                print("you have", FighterLvl1.Gold, 'gold ')
                del goblin
    def LevelUp(self):
        MrHezy = FighterLvl2(Player_Character)

class FighterLvl2(Player_Character):
    def LevelUp(self):
        MrHezy = FighterLvl3(Player_Character)

class FighterLvl3(Player_Character):
    def MaxLevel(self):
        print("Congratulations you are level 3, this is the highest programmed level in the game 
               ")

class goblin:
    def __init__(self, HP, MaxHP, AC, ToHitAdjustment, Surprise_Adjustment, 
                 Initiative_Adjustment, \
                 ExpReward, Gold, Damage):
        self.HP = int(HP)
        self.MaxHP = int(MaxHP)
        self.AC = int(AC)
        self.ToHitAdjustment = int(ToHitAdjustment)
        self.Surprise_Adjustment = int(Surprise_Adjustment)
        self.Initiative_Adjustment = int(Initiative_Adjustment)
        self.ExpReward = int(ExpReward)
        self.Gold = int(Gold)
        self.Damage = int(Damage)

    def attack(self, Player_Character, goblin):
        if (goblin.HP <= 0):
            print("the goblin is inert")
        else:
            goblin_attack_roll = d20.die_roll() + goblin.ToHitAdjustment
            if (goblin_attack_roll >= Player_Character.AC):
                goblin_damage = d4.die_roll()
                print("you take", goblin_damage, 'damage')
                Player_Character.HP -= goblin_damage
                if (Player_Character.HP <= 0):
                    print("oh dear you have died")
                    del Player_Character
                    quit()
            else:
                print("the goblin misses ")

MrHezy = Player_Character(20, 20, 10, 5, 0, 0, 0, 25, 0, d10.die_roll())


def spawn_goblin(goblin):
    G1 = goblin(5, 10, 8, 2, 0, 0, 25, 5, d4.die_roll())
    return G1

goblin1 = spawn_goblin(goblin)

def battle(goblin1):

    # user input
    player_initiative_adjustment = MrHezy.Initiative_Adjustment
    monster_initiative_adjustment = goblin1.Initiative_Adjustment

    #define while loop for the battle
    while True:
        if (goblin1.HP <= 0):
            print('oh dear looks like we need a new goblin')
            break
        #use random.randint(a,b) to generate player and monster base initiative
        player_base_initiative = d10.die_roll()
        monster_base_initiative = d10.die_roll()

        #subtract the adjustment to get player and monster initiative
        player_initiative = player_base_initiative - player_initiative_adjustment
        monster_initiative = monster_base_initiative - monster_initiative_adjustment

        #compare the initiatives and display the results
        if (player_initiative < monster_initiative):
            attack_flee_heal = input("congratulations you go first. Would you like to attack, 
                                      flee, or heal?")
            if attack_flee_heal == 'attack':
                MrHezy.attack(goblin1, MrHezy)
            elif attack_flee_heal == 'heal':
                MrHezy.heal(MrHezy)
                print("the goblin attacks")
                goblin1.attack(MrHezy)
            elif attack_flee_heal == 'flee':
                MrHezy.flee()
        else:
            print("uhoh, the monsters go first, they attack!")
            goblin1.attack(MrHezy, goblin1)
            attack_flee_heal = input("Would you like to attack, flee, or heal? ")
            if attack_flee_heal == 'attack':
                MrHezy.attack(goblin1, MrHezy)
            elif attack_flee_heal == 'heal':
                MrHezy.heal(MrHezy)
                print("the goblin attacks")
                goblin1.attack(MrHezy, goblin1)
            elif attack_flee_heal == 'flee':
                MrHezy.flee()



#main game loop
while True:
    spawn_goblin(goblin)
    battle(goblin1)
    print("spawn another goblin")
    goblin1.HP = 0
    goblin1.HP += d10.die_roll()

此代码运行良好,请将其输入到您的 IDE 中。 我遇到的问题是逻辑错误,当一个地精被杀死而不是先将角色升级到 1 级然后 2 级然后 3 级而不是角色一遍又一遍地升级到 1 级时。

【问题讨论】:

  • 其实我不确定它是否一遍又一遍地升级到1级,它可能只是说它是......
  • 当您在导入随机模块后将其复制并粘贴到 IDE 中时,您需要使用 ctr+r 来查找和替换所有骰子实例,例如 d10 hit ctr +r 然后输入 random.randint(1,10)
  • * 在 pycharm IDE 中按 ctrl+r 然后键入 d10.die_roll() 替换为 random.randint(1,10)

标签: python-3.x oop object inheritance


【解决方案1】:

我同意 Danny Varod 的观点,因为有很多地方需要改进,我绝对建议听从他的建议。

但是,如果您只是想让您有工作,您需要在您的升级方法中指定您引用全局 MrHezy 变量。

例如:

def LevelUp(self):
    global MrHezy
    MrHezy = FighterLvl2(Player_Character)

【讨论】:

  • 当我将 MrHezy 设为你所说的全局(LevelUp 方法 2)时,它没有任何效果。当我在第一个 LevelUp 方法上执行此操作时,它似乎可以将我的玩家升级到 FighterLvl1 我遇到了原始帖子中提到的继承问题。由于某种原因 FighterLvl1 没有继承 Player_Character 的所有属性,我如何让 FighterLvl1 继承 Player_Character 的所有属性?
  • PS 当我实现这个方法时,当我试图获得 exp 时它会崩溃(因为某种原因它没有被继承)但我认为这是朝着正确方向迈出的一步。
  • 每次你想像这样改变它时,你都需要让 MrHeazy 全局化。我只是以2级以上的等级为例。
  • 就您遇到的继承问题而言,我假设您希望将 Player_Character 的所有实例属性传递给 FighterLevel1 等。为此,您需要实际传递它们。跨度>
【解决方案2】:

level up 替换了对象中的一个变量,你应该怎么做,如果你想每级使用一个类(不一定是好主意)是:

创建一个Character 类。

Character 类中定义一个implementation 字段。

初始化implementation 字段,例如implementation = SomeSpeciesLevel1().

要“升级”:implementation = implementation.level_up()

这样你就有了一个不变的包装器,它包装了级别更改的实现。

更好的设计是让一个类具有基于级别相关公式的功能。

class CharImpl:
    @abstractmethod
    def can_level_up() -> bool:
        return NotImplemented
    @abstractmethod
    def next_level() -> CharImpl:
        return NotImplemented
    pass

class Character:
    def __init__(initial_impl: CharImpl=None):
        self.impl = initial_impl.copy() if initial_impl else HumanLevel1()
        pass
    def level_up():
        if self.impl.can_level_up():
            self.impl = self.impl.next_level()
        pass
    pass

class Human(CharImpl):
    pass

class HumanLevel1(Human):
    def __init__(src: Human):
        # TODO: copy relevant fields from src
        pass
    def can_level_up() -> bool:
        return True
    def next_level() -> CharImpl:
        return HumanLevel2(self)
    pass

class HumanLevel2(Human):
    def __init__(src: Human):
        # TODO: copy relevant fields
        pass
    def can_level_up() -> bool:
        return False
    def next_level() -> CharImpl:
        return self
    pass

【讨论】:

  • 我应该怎么做才能升级?你能推荐一些阅读材料吗?我不确定如何实现你的答案,你能告诉我使用我的代码吗?
  • @HezekiahBodine 抱歉,但您的代码是问题所在,您应该重构它。我建议了一种模式,您可以在我的回答中使用代码示例。我建议您阅读有关面向对象编程以及使用不可变对象进行函数式编程的内容。此外,每个级别的类是不可扩展的,而是考虑根据类更改其他字段,例如力量、技巧、运气等。
  • 很抱歉,但我仍然无法弄清楚如何实施您的解决方案。您的“实施领域”与我的“LevelUp”方法有何不同?
  • 你能告诉我如何使用“Player_Character”作为基类和“FighterLvl1”作为第一级来实现你的方法吗?
  • @HezekiahBodine 查看新示例
猜你喜欢
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多