質問: 初心者です。初歩的な質問ですいません。 テキストでRPGの戦闘を題材にクラスの継承を勉強中です。 出題された問題は、勇者・戦士と魔法使いでは表示される文言を変えて出すために継承を利用していました。 print(self.name+"は"+enemy+"を攻撃した") #戦士、勇者の時 print(self.name+"は"+enemy+"に魔法を唱えた") #魔法使いの時 問題はクリアしたのですが、できればついでにもう少しリアルにしたいので、 魔法使いの攻撃については、wizardクラスのattackメソッドにある「魔法」に種類を追加したいです。 「炎」 「風」 「水」 などで、「魔法使いはスライムに炎を唱えた」などと表示されるようにしたいです。 ``` class Player(): def __init__(self,name,spell): self.name=name self.spell=spell def attack(self,enemy): print(self.name+"は"+enemy+"を攻撃した") class Wizard(Player): def attack(self,enemy,spell): print(self.name+"は"+enemy+"に"+self.spell+"を唱えた") hero=Player("勇者") warrior=Player("戦士") wizard=Wizard("魔法使い") party=[hero,warrior,wizard] for player in party: if player==wizard: maho=["fire","water","riot"] fire=(Wizard("炎")) water=(Wizard("水")) riot=(Wizard("雷")) for spell in maho: spell.attack() else: player.attack("スライム") ``` spellの使い方でエラーが出てしまいます。 Traceback (most recent call last): File "Main.py", line 15, in hero=Player("勇者") TypeError: *init*() missing 1 required positional argument: 'spell' どのようにspellを使えばいいのでしょうか? 上の文章だと、spellがオブジェクトになってしまっているのだと思います。
回答: コードがちゃんと読めないので憶測も多少混じりますが、 ``` class Wizard(Player): def attack(self,enemy): print(self.name+"は"+enemy+"に魔法を唱えた") ``` は仮に継承をしなかったとしたら、こういうコードになります。 ``` class Wizard: def __init__(self, name): self.name=name def attack(self, enemy): print(self.name+"は"+enemy+"に魔法を唱えた") ``` なので、`Wizard("炎")`などとすると`炎は<敵>に魔法を唱えた`ってなっちゃう、ってことかな? これの修正はゲームデザインによります。炎属性の魔法しか使えない魔法使い、みたいな設定にするなら、`__init__`をオーバーライドして属性を引き受けることになります。 ``` class Wizard(Player): def __init__(self, name, magic_type): self.name = name self.magic_type = magic_type def attack(self,enemy): print(self.name + "は" + enemy + "に" + self.magic_type + "を唱えた") ``` みたいな感じですかね。インスタンス化するときは`Wizard("魔法使い", "炎")`みたいにしてください。 あるいは、`attack`に追加するというのもあるでしょう。そうするといろいろな種類の魔法が使える魔法使いになれます。 ``` class Wizard(Player): def attack(self, enemy, magic_type): print(self.name + "は" + enemy + "に" + magic_type + "を唱えた") ``` ただし、`attack`の呼び方が変わります。なので質問文のようなループでは対応できないですね。 あるいは、「覚えてる魔法」を保持する`set`でもインスタンスに持たせて、その中から相性を見てベストなのを選択するとか。やり方はいろいろあるかと。