800行のコードで行動木(Behavior Tree)のライブラリを作る(3)
4741 ワード
転入先http://www.aisharing.com/archives/530
行動木の最後にお話しするのは、前提(Precondition)についてです.第1部では、少しお話ししましたが、今回は、前提の純虚基類の定義をよく見てみましょう.
各前提クラスには,この判断を実現する虚関数が必要である.私は『クラスで論理演算を表すC行為木の前提の一つの実現方式』で、私たちはクラスで論理演算を表すことができて、このような利点はモジュール化することができて、同じ判断条件は多重化することができて、だからライブラリの中で、私もこのような論理の表現方式を実現して、基本的な論理演算クラスを定義しました
これらのクラスの名前から明らかなように、これらのクラスの意味は、論理オペレータと同様に、いくつかのクラスの構造関数には2つのパラメータが必要であり、これによって2元の論理演算(AND,OR,XOR)を表し、一部は1つのパラメータだけが必要であり、これによって1元の論理演算(NOT)を表す.前提クラスは動作ツリーのノードにアタッチするために使用され(各ノードにアタッチ可能)、デフォルトでは、ノードに前提クラスがない、すなわち「外在前提」が存在せず、「内在前提」のみであり、これはBevNodePreconditionTRUE(Trueに永遠に戻る)がアタッチされた「外在前提」のノードと等価である.
さあ、行動ツリーライブラリの内容は基本的にこれらです.次に例プログラムを見てみましょう.ライブラリで動作ツリーを作成する方法を紹介します.例のコードはBevTreeTestというプロジェクトで、コンパイル後に直接実行できます.この例では、簡単から複雑まで、3つの動作ツリーをそれぞれ示しています.マウスをクリックすると、この3つの例を切り替えることができます.このプログラムは,「シーンマップ上では,タイミング的にターゲットポイントが生成され,スマートボディは動作ツリーの定義に基づいて異なる動作モードでターゲットポイントに移動する」という機能を実現している.
このプログラムでは、スマートボディの4つの動作を定義しました.
さらに2つの「外在的前提」を定義しました.
最初の例では、最初の例の動作ツリー図は次のようになります.
これは簡単な動作ツリーで、ルートノードは優先度のある選択ノードなので、MoveToはIdleより優先度が高く、MoveToは「外在的前提」を持ち、「目標点に達していない」場合はMoveToでの動作を選択し、逆にIdleでの動作を選択します.
コードでは、この動作ツリーを定義できます.
関連ノードの作成を支援するために、ライブラリにいくつかのファクトリメソッドを定義しました.ここでは,クラスで論理を表す使い方を実証した.私は動作ツリーを定義するときに、対応する親子構造をいくつかのフォーマットのインデントで表します.これは視覚的に明らかにするためだけです.もちろん、後で動作ツリーの定義インタフェースを改善したり、データファイルで動作ツリーを定義したりすることができます.
定義が完了すると、動作ツリーで動作を決定できます.コードはかなり簡単です.
例では、スマートボディの情報を直接修正するのではなく、BevNodeOutputParam構造に出力する変数をできるだけ書きます.このようなメリットは、動作ツリーの入力と出力のインタフェースをかなり明確にし、ブラックボックスを作ることができ、ここでの議論を参考にすることができます.
2つ目の例ではパラレルノードの使い方を示し,3つ目の例ではシーケンスノードの使い方を示したが,あまり話さず,コードを自分で見ることができる.
すべてのコードは以下の方法で入手できます.
ダウンロード先:
GoogleCodeダウンロードポイント(exeフォルダに実行可能ファイルが含まれています)
svnは、次のアドレスで取得することもできます.
http://tsiu.googlecode.com/svn/branches/blogver/
コンパイル方法:
VS 2005以上で開く、Debug NoDxまたはRelease NoDxを選択し、コンパイル後、BevTreeTestを実行する.
関連コード:
TAI_BevTree.h
TAI_BevTree.cpp
TsiUについて
TsiUは私がずっとメンテナンスしている小型のフレームワークです.私が普段作っているAIのsampleやツールは、このフレームワークに基づいています.TsiUには基本的なUIコントロールライブラリ、ネットワークモジュールライブラリ、GDIグラフィックスモジュール、D 3 Dグラフィックスモジュールなどがあります.小型のサンプルプログラムを迅速に作成することができます.便利(具体的にはSampleAppsの例プログラムを参照できます)、アーキテクチャ全体がObjectで組織されており、理解しやすく拡張しやすいです.全体のフレームワークはとても軽量化して、基本的にいくつかの下層の基本的な機能をして、このように私はふだんものをする時、下層を書き直す必要がなくて、精力を上層部の実現に置きました.後でコードを共有するのはすべてこのフレームワークに基づいて、みんなもsvnを通じていつでもupdateを私の最新の変更に変えることができます.下の図はTsiUのいくつかの工事の紹介で、コードは多くなくて、みんなが見たいのも自分で見ることができます:)
行動木の最後にお話しするのは、前提(Precondition)についてです.第1部では、少しお話ししましたが、今回は、前提の純虚基類の定義をよく見てみましょう.
1: class BevNodePrecondition
2: {
3: public:
4: virtual bool ExternalCondition(const BevNodeInputParam& input) const = 0;
5: };
各前提クラスには,この判断を実現する虚関数が必要である.私は『クラスで論理演算を表すC行為木の前提の一つの実現方式』で、私たちはクラスで論理演算を表すことができて、このような利点はモジュール化することができて、同じ判断条件は多重化することができて、だからライブラリの中で、私もこのような論理の表現方式を実現して、基本的な論理演算クラスを定義しました
1: class BevNodePreconditionTRUE{};
2: class BevNodePreconditionFALSE{};
3: class BevNodePreconditionNOT{};
4: class BevNodePreconditionAND{};
5: class BevNodePreconditionOR{};
6: class BevNodePreconditionXOR{};
これらのクラスの名前から明らかなように、これらのクラスの意味は、論理オペレータと同様に、いくつかのクラスの構造関数には2つのパラメータが必要であり、これによって2元の論理演算(AND,OR,XOR)を表し、一部は1つのパラメータだけが必要であり、これによって1元の論理演算(NOT)を表す.前提クラスは動作ツリーのノードにアタッチするために使用され(各ノードにアタッチ可能)、デフォルトでは、ノードに前提クラスがない、すなわち「外在前提」が存在せず、「内在前提」のみであり、これはBevNodePreconditionTRUE(Trueに永遠に戻る)がアタッチされた「外在前提」のノードと等価である.
さあ、行動ツリーライブラリの内容は基本的にこれらです.次に例プログラムを見てみましょう.ライブラリで動作ツリーを作成する方法を紹介します.例のコードはBevTreeTestというプロジェクトで、コンパイル後に直接実行できます.この例では、簡単から複雑まで、3つの動作ツリーをそれぞれ示しています.マウスをクリックすると、この3つの例を切り替えることができます.このプログラムは,「シーンマップ上では,タイミング的にターゲットポイントが生成され,スマートボディは動作ツリーの定義に基づいて異なる動作モードでターゲットポイントに移動する」という機能を実現している.
このプログラムでは、スマートボディの4つの動作を定義しました.
1: class NOD_Idle{}; // ,
2: class NOD_Breathe{}; // ,
3: class NOD_MoveTo{}; // ,
4: class NOD_FaceTo{}; // ,
さらに2つの「外在的前提」を定義しました.
1: class CON_HasReachedTarget{}; //
2: class CON_HasFacedToTarget{}; //
最初の例では、最初の例の動作ツリー図は次のようになります.
これは簡単な動作ツリーで、ルートノードは優先度のある選択ノードなので、MoveToはIdleより優先度が高く、MoveToは「外在的前提」を持ち、「目標点に達していない」場合はMoveToでの動作を選択し、逆にIdleでの動作を選択します.
コードでは、この動作ツリーを定義できます.
1: BevNode& ret =
2: BevNodeFactory::oCreatePrioritySelectorNode(NULL, "root");
3: BevNodeFactory::oCreateTeminalNode<NOD_MoveTo>(&ret, "move to")
4: .SetNodePrecondition(new BevNodePreconditionNOT(new CON_HasReachedTarget()));
5: BevNodeFactory::oCreateTeminalNode<NOD_Idle>(&ret, "idle")
6: .SetNodePrecondition(new BevNodePreconditionTRUE());
7: m_BevTreeRoot = &ret;
関連ノードの作成を支援するために、ライブラリにいくつかのファクトリメソッドを定義しました.ここでは,クラスで論理を表す使い方を実証した.私は動作ツリーを定義するときに、対応する親子構造をいくつかのフォーマットのインデントで表します.これは視覚的に明らかにするためだけです.もちろん、後で動作ツリーの定義インタフェースを改善したり、データファイルで動作ツリーを定義したりすることができます.
定義が完了すると、動作ツリーで動作を決定できます.コードはかなり簡単です.
1: BevNodeInputParam input(&m_BevTreeInputData);
2: BevNodeOutputParam output(&m_BevTreeOutputdata);
3: if(m_BevTreeRoot->Evaluate(input))
4: {
5: m_BevTreeRoot->Tick(input, output);
6: }
例では、スマートボディの情報を直接修正するのではなく、BevNodeOutputParam構造に出力する変数をできるだけ書きます.このようなメリットは、動作ツリーの入力と出力のインタフェースをかなり明確にし、ブラックボックスを作ることができ、ここでの議論を参考にすることができます.
2つ目の例ではパラレルノードの使い方を示し,3つ目の例ではシーケンスノードの使い方を示したが,あまり話さず,コードを自分で見ることができる.
すべてのコードは以下の方法で入手できます.
ダウンロード先:
GoogleCodeダウンロードポイント(exeフォルダに実行可能ファイルが含まれています)
svnは、次のアドレスで取得することもできます.
http://tsiu.googlecode.com/svn/branches/blogver/
コンパイル方法:
VS 2005以上で開く、Debug NoDxまたはRelease NoDxを選択し、コンパイル後、BevTreeTestを実行する.
関連コード:
TAI_BevTree.h
TAI_BevTree.cpp
TsiUについて
TsiUは私がずっとメンテナンスしている小型のフレームワークです.私が普段作っているAIのsampleやツールは、このフレームワークに基づいています.TsiUには基本的なUIコントロールライブラリ、ネットワークモジュールライブラリ、GDIグラフィックスモジュール、D 3 Dグラフィックスモジュールなどがあります.小型のサンプルプログラムを迅速に作成することができます.便利(具体的にはSampleAppsの例プログラムを参照できます)、アーキテクチャ全体がObjectで組織されており、理解しやすく拡張しやすいです.全体のフレームワークはとても軽量化して、基本的にいくつかの下層の基本的な機能をして、このように私はふだんものをする時、下層を書き直す必要がなくて、精力を上層部の実現に置きました.後でコードを共有するのはすべてこのフレームワークに基づいて、みんなもsvnを通じていつでもupdateを私の最新の変更に変えることができます.下の図はTsiUのいくつかの工事の紹介で、コードは多くなくて、みんなが見たいのも自分で見ることができます:)