2016-08-09 4 views
0

たとえば、私は単純なゲームのための敵クラスを構築しようとしています。各の敵にはタイプのがあり、これはの敵クラスのフィールドであるstatsに影響します。クラスはいつサブクラスを保証しますか?

class Enemy: 
    #Base Stats for all enemies 
    name = "foo" 
    current_health = 4 
    max_health = 4 
    attack = 0 
    defense = 0 
    armor = 0 
    initiative = 0 
    initMod = 0 
    alive = True 

タイプ

class goblin(Enemy): 
    name = goblin; 
    current_health = 8 
    max_health = 8 
    attack = 3 
    defense = 2 
    armor = 0 

    def attack(){ 
     //goblin-specific attack 
    } 

...そうのようサブクラスの敵なるべきであるが、この方法は、私は、個々のタイプのクラスを構築しなければならないことを意味し(これは80以上のクラスになります)、それとももっと良い方法がありますか?このは、ランダム化されようとしているので、私はまた、キーワードとして種類の名前を使用しています辞書に入れることができタイプを考えていました。私はそれをどのように実装できるかは完全にはわかりませんが。

+0

多くの潜在的なサブクラスを使用すると、おそらく問題をよくモデリングできません。 1つは、「is-a」と「has-a」の関係、場合によってはクラスとクラスのインスタンスを混同しているように思えます。リストされた属性のほとんどは、おそらくクラスまたはサブクラスのコンストラクタ( '__init __()')で初期化されます。また、クラスメソッドのすべての定義は自動的に、クラスのインスタンスである 'self'と呼ばれる第1引数を自動的に受け取ります。だから、あなたは 'def attack(self):'を持つ必要があります。また、Pythonはそのように '{'と '}'を使用しません。 – martineau

答えて

0

あなたは、キーによって返されるタプルでこのような何かを行うことができ辞書ルートに行きたい場合は:あなたは

https://stackoverflow.com/a/13700868/2489837

named_tupleを使用したい場合がありますが

enemy_types = {"goblin": ("goblin", 8, 8, 3, 2, 0, goblin_attack)} 

def goblin_attack(enemy): 
    do_stuff() 

タプルのフィールドを混同しないようにする

+0

私はこれが私が納得する道だと思う。しかし、明確にするために、すべての敵は戦闘に関する同じガイドラインに従います。彼らはすべて攻撃または守ることができますが、彼らの攻撃中に行うことは、彼らの特別な能力に基づいて異なる可能性があります。私は辞書にある敵のタイプごとに別々の関数を作成する必要がありますか?そして、それらの機能は私の敵のクラスファイルに存在するでしょうか? – Czurch

+0

それはあなた次第です。私のすべての解決策は、関数のポインタを返すことです。彼らの特殊攻撃が何であるかに応じて(つまり、ダメージの程度を示すパラメータを渡すことができますか、それともそれに関連する特別なものがありますか)、それぞれに固有の機能が必要な場合があります。いずれにせよ、あなたはまだこの辞書のルートを取ってタプル/オブジェクトを返すことができます。 –

0

各敵タイプの属性と可能なアクション私は、タイプの80項目の列挙を定義し、Enemyと呼ばれる単一のクラスを使用するより複雑な何かをする理由は見ません。

さまざまな操作が必要な場合は、80種類をさまざまなコレクションにグループ化して共通の属性(たとえば、FlyingEnemyUndeadEnemyなど)にすることができます。それらはあなたのサブクラスになります。

+0

私は本当にこのアイデアが好きです、それはまた、別の敵のための辞書を使用するuser2489837のアイデアで動作することができますか?このように私はFlyingEnemiesまたはUndeadEnemiesのリストを持つことができました。 – Czurch

0

ゴブリンはおそらく敵のインスタンスであるべきです。しかし、あなたの例では、attackというメソッドを追加しました。

class Enemy: 
    #Base Stats for all enemies 
    def __init__ (self, **kwargs): 
    self.name = "foo" 
    self.current_health = 4 
    self.max_health = 4 
    self.attack = 0 
    self.defense = 0 
    self.armor = 0 
    self.initiative = 0 
    self.initMod = 0 
    self.alive = True 
    # Use this to specify any other parameters you may need 
    for key in kwargs: 
     exec ("self.%s = %s" % (key, kwargs[key]) 

今、あなたがゴブリンと呼ばれるEnemyのインスタンスを作成することができます:私はこれを行うための最善の方法は次のようであると言うでしょう。

サブクラスを使用する場合の最初の質問に答えるには、サブクラスを使用することは素晴らしいですが、あなたのケースでは複雑すぎるかもしれません。サブクラスには1つのメソッドしかないので、簡単にモジュールを作成しての引数にattack関数を指定することができます。これにより、コードがより簡単になります。

注:サブクラスを使用しようとしている場合は、あなたのサブクラスの__init__にあなたがsuper()とあなたの基本クラスの__init__を呼び出していることを確認してください。

+0

最後の 'for'ループ全体を' self .__ dict __。update(kwargs) 'に置き換えることができます。一般的には、できるだけ 'exec'を使うのを避けたいと思っています。インデントも矛盾しています(4スペースではありません。[PEP 8 - スタイルガイド、Pythonコード](https://www.python.org/dev/peps/pep-0008/)を参照)。 – martineau

+0

辞書に関する知識が不足していることをお詫びしますが、ここで何をやっているのか分かりました。だから私はすべての異なる敵のタイプの辞書を定義していたでしょう。私は敵の新しいインスタンスを作成するとき、私はそれらの敵の1つの鍵を入力する必要があります。そのキーは、ディクショナリ内の型を参照するために使用され、敵フィールドをディクショナリで指定された値に初期化します。 p.s.答える時間をとってくれてありがとう – Czurch

関連する問題