1

私はゲームを開発しています。ゲーム内の各エンティティはGameObjectです。それぞれGameObjectは、、、およびで構成さGameObjectControllerGameObjectModelますGameObjectView。(またはその継承者。)

NPCの場合、GameObjectControllerは次のように分割されます。

IThinkNPC:現在の状態を読み取り、何をすべきかを決定します

IActNPC:実行する必要があることに基づいて状態を更新します

ISenseNPC:現在の状態を読み取って世界の質問に答えます(例:「私は影に隠れていますか?」)

私の質問:これはISenseNPCインターフェースに問題はありませんか?

public interface ISenseNPC
    {
        // ...

        /// <summary>
        /// True if `dest` is a safe point to which to retreat.
        /// </summary>
        /// <param name="dest"></param>
        /// <param name="angleToThreat"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        bool IsSafeToRetreat(Vector2 dest, float angleToThreat, float range);

        /// <summary>
        /// Finds a new location to which to retreat.
        /// </summary>
        /// <param name="angleToThreat"></param>
        /// <returns></returns>
        Vector2 newRetreatDest(float angleToThreat);

        /// <summary>
        /// Returns the closest LightSource that illuminates the NPC.
        /// Null if the NPC is not illuminated.
        /// </summary>
        /// <returns></returns>
        ILightSource ClosestIlluminatingLight();

        /// <summary>
        /// True if the NPC is sufficiently far away from target.
        /// Assumes that target is the only entity it could ever run from.
        /// </summary>
        /// <returns></returns>
        bool IsSafeFromTarget();
    }

どのメソッドもパラメータを取りません。代わりに、実装は関連するものへの参照を維持し、GameObjectControllerそれを読むことが期待されます。

しかし、私は現在、このための単体テストを作成しようとしています。もちろん、引数を直接渡すことはできないので、モッキングを使用する必要があります。私のやり方は本当にもろく感じます-ワールドクエリユーティリティを別の方法で使用する別の実装が登場した場合はどうなりますか?実際、私はインターフェースをテストしていません。実装をテストしています。貧しい。

そもそもこのパターンを使用した理由は、IThinkNPC実装コードをクリーンに保つためでした。

    public BehaviorState RetreatTransition(BehaviorState currentBehavior)
    {
        if (sense.IsCollidingWithTarget())
        {
            NPCUtils.TraceTransitionIfNeeded(ToString(), BehaviorState.ATTACK.ToString(), "is colliding with target");
            return BehaviorState.ATTACK;
        }

        if (sense.IsSafeFromTarget() && sense.ClosestIlluminatingLight() == null)
        {
            return BehaviorState.WANDER;
        }

        if (sense.ClosestIlluminatingLight() != null && sense.SeesTarget())
        {
            NPCUtils.TraceTransitionIfNeeded(ToString(), BehaviorState.ATTACK.ToString(), "collides with target");
            return BehaviorState.CHASE;
        }
        return currentBehavior;
    }

おそらく、清潔さはそれだけの価値はありません。

したがって、ISenseNPC毎回必要なすべてのパラメータを取得する場合は、静的にすることができます。何か問題はありますか?

4

1 に答える 1

2

いいえ。ダメダメダメ。AIに、とんでもない数の非表示の(非表示ではない)依存関係を作成しています。まず、MVCはここで使用するのに適したパターンではありません。気にする必要のある「ビュー」が実際にはなく、アクションのみが存在するためです。また、ここでの「モデル」は、実際には当時のAIに知られている世界の状態であり、AI自体とは完全に分離されていますが、これはゲームの世界の「ビュー」と見なすことができます。オブジェクトの位置と属性のスナップショット(私はこの方法で作成しましたが、非常に効果的でした)。

ただし、主要な問題は、retreatTransitionコードがアクションと状態に高度に結合されていることです。変更を加える必要がある場合はどうなりますか?すべて類似した200種類のAIが必要な場合、それをどのように維持しますか?答えはあなたができなかったということです、それは混乱になるでしょう。ここでステートマシンを効果的に作成しているのですが、ステートマシンは適切に拡張できません。また、コードを編集せずにマシンから状態を追加/変更/削除することはできませんでした。

代わりに、別のアーキテクチャへの移行を検討することをお勧めします。ここでのTDDアプローチは優れていますが、選択する前に、一歩下がってさまざまなAIアーキテクチャを確認し、コアコンセプトを理解する必要があります。まず、FEARの目標ベースのアーキテクチャに関するJeff Orkinの優れた記事「3つの状態と計画」(http://web.media.mit.edu/~jorkin/goap.html)を見ていきます。私は以前にこれを実装しましたが、非常に効果的で愚かで、設計と保守が簡単でした。そのコア設計は、TDD(実際にはBDDがより良い選択です)を非常にうまく促進します。

もう1つ、ISenseNPCは、世界の状態と緊密に結合しているように見えます。AIの認識(世界から観察できるもの)は完全に分離されている必要があるため、これは、クラスWorldModelまたはISenseNPCオブジェクトに渡される何かが必要であり、WorldModelが関連するかどうかを検査する必要があることを示しています。知覚を介した情報(AIが世界を知覚できる方法として知覚を考えてください。センサー、視界半径、ソナーなど)。さらに、個々の知覚を作成してISenseNPCに追加することもできます。これにより、分離されます。世界の状態、AIがその世界を認識する方法、そしてAIが世界自体を理解する方法。そこから、AIは何をすべきかを決定できます。

単純な反射エージェントをモデル化しています。これは、特定の知覚シーケンスに応答する一連のルールであり、単純なAIには適しています。これは基本的には栄光のステートマシンですが、Thinkオブジェクトの動作に対する知覚のマッピングを作成できます。これは個別に維持でき、そのマッピングを変更または拡張する場合、コードを変更する必要はありません(単一責任原則が機能します)。さらに、すべての知覚、決定、およびアクションを列挙し、特定のAIに対してそれらをリンクできるゲームエディターを作成できます。これにより、ゲームに参加したり、コードを再構築したりすることなく、AIを維持することが容易になります(潜在的に) 。これは、ここでやろうとしていることよりもはるかに柔軟で保守しやすいことがわかると思います。この特定のもののためにそのMVCを捨てる、

これについて他にご不明な点がありましたらお知らせください。ゲームの目標ベースのアーキテクチャの実装やその他の経験がありますので、喜んでお手伝いさせていただきます。

于 2011-04-11T23:16:30.933 に答える