2

私は単純な進化的AIに取り組んでいます。匿名関数を動的に生成する必要があります。そのために、条件とアクションのリストがあります。

   var conditions = [
    function () { return enemyNear(), }, 
    function () { return mySpeed() > 5; }, 
    function () { return 1 === 1; }];
   var actions = [
      function () { return alert('walk'); },
      function () { return alert('jump'); } 
      function () { return alert('attack'); } ]

コードは、それぞれ1つを選択して、新しい関数を生成します。

condition = conditions [Math.floor(Math.random()*conditions .length)];
actions = conditions [Math.floor(Math.random()*actions .length)];

選択した条件がenemyNear()であり、選択したアクションがwalk()である場合、単純な無名関数を生成するにはどうすればよいですか?

behavior = function() {
    if(enemyNear()) {
        walk();
    }
}

必要に応じて、配列の保存方法を変更できます。これはどのように行うことができますか?

すべての文字behaviorsは、次のようにループ内で呼び出されます。

for(i=0,i<chars.length,i++) {
chars[i].behavior.call();
}
4

6 に答える 6

4

最も簡単な方法は、配列内に関数を配置することだけです。

var conditions = [
    enemyNear, 
    function () { return mySpeed() > 5; }, 
    function () { return 1 === 1; 
}];
var actions = [walk, attack, jump];

behave次に、次のように定義できます。

var behave = function(condition, action) {
    if(condition()) {
        action();
    }
}

そして、たとえば次のように使用します。

behave(conditions[2], actions[1]);

ここでは、21のようにランダムに生成された数値である可能性があります。

var getRandomInt = function (min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

var actRandomly = function (conditions, actions) {
    behave(
        conditions[getRandomInt(0, conditions.length -1)],
        actions[getRandomInt(0, actions.length -1)]
    );
};

次のように呼びます:

actRandomly(conditions, actions);

もちろん、これはアイデアを提示するだけであり、きちんと整理されていません。

それを楽しむために、私は基本的なjsFiddleデモバージョンを作成しました。


注:var変数を定義するときは常に使用してください。グローバルスコープを汚染しないでください。

于 2012-12-21T00:23:43.167 に答える
3

これから配列を変更します。

conditions = [enemyNear(), mySpeed()>5, 1=1];

これに:

conditions = [
    function() { return enemyNear() },  // or just enemyNear
    function() { return mySpeed() > 5 },
    function() { return 1 == 1 } // 1 = 1?
];

現在のコードでは、関数が呼び出され、conditionsそれらの関数の出力の配列になります。

于 2012-12-21T00:22:05.287 に答える
3

まず、配列の内部で、条件とアクション関数への参照が必要になります。今、あなたはそれらを呼んでいるので、それらは基本的に次のような役に立たない配列と同じです:

conditions = [true, false, true];
actions = [undefined, undefined, undefined];

私はそれを次のように修正します:

var conditions = [enemyNear, 
  function() { return mySpeed() > 5 }, 
  function(){ return true; }];
var actions = [walk, attack, jump];

次に、動作を生成する関数を作成できます。

function generateBehavior(){
  var condition = conditions[Math.floor(Math.random() * conditions.length)];
  var action = actions[Math.floor(Math.random() * actions.length)];
  return function() {
    if(condition()) {
      action();
    }
  }
}

このJSFiddleデモで実際の動作を確認できます。

于 2012-12-21T00:25:57.100 に答える
1
condition = [
    enemyNear,
    function() { return mySpeed() > 5; },
    function() { return 1 == 1; }
];
于 2012-12-21T00:24:25.320 に答える
0

関数を呼び出すのではなく、に格納する必要がありますarray。そうしないと、関数の結果が配列に格納されます。

function enemyNear() {}
function walk() {}

conditions = [enemyNear]
actions = [walk]

behaviour = function() {
  if(conditions[randomNumber]()) {
    actions[randomNumber]();
  }
}
于 2012-12-21T00:23:29.063 に答える
-6

単純。eval()を使用する

var behavior;
eval("behavior = function() { if (enemyNear()) walk(); }");
behavior();
于 2012-12-21T00:23:18.907 に答える