2016-03-21 10 views
1

Node.jsで書かれたAgar.ioサーバーの実装であるOgarというプロジェクトのボットを作っています。障害物を避けて円を描く角度を計算する

このボットには障害があり、ウイルスと呼ばれる緑色のスパイク状の細胞があります(イラスト参照)。私はこの障害を避けるためにこのボットをプログラムする必要がありますが、私は運がないです。イラストのようなターゲットがたくさんあるので、アップデートに基づいています。

Illustration of what I want

ここで私は今までになってしまったコードです。

BotPlayer.prototype.avoidObstacles = function(cell, angle) { 
    // Sum up all of the vector angles of obstacles to cell and react against it 
    var angleSum = 0; 
    var collided = this.collisionFromList(cell, this.obstacles); 
    if (collided.length == 0) return angle; // Not to return NaN 

    for (var i = 0; i < collided.length; i++) { 
     angleSum += this.angle(cell.position, collided[i].position); 
    } 

    angleSum /= collided.length; // Average out the angle sum 

    // TODO: Find closest available edge 
    angleSum += Math.PI/2; 

    return angle + angleSum; 
}; 

これは、ほとんどの場合、作業を行いますが、ボットは時々完全に障害物を無視します(this.collisionFromList(cell, this.obstacles);はまったく問題あり)と、文字通り(細胞の多くに爆発する)、それを通過してしまいます。

BotPlayer.prototypeには、この種の計算に多くの便利な機能があります。 this linkを参照してください。

私はパスファインダーを必要としません。この簡単な対策はありません。

+0

3つの等間隔障害物や、あなたのボットは、中央障害物に向かっているがある場合、あなたは、角度計算が途中障害物に向かうボットを維持しないだろう? –

答えて

1

あなたがしようとしていることに対する代替アプローチがあります。アプローチはアトラクタを使用してシステム内のエンティティを記述することです。あなたの "ボット"はagentで、ポジションを持ち、世界の他のエンティティとその誘因力を知っています。あなたの目的地が+1 attractionの力と障害が-X attractionの力を持っていて、効果的に "ボット"(agent)を撃退しているとします。

ここで決定擬似コードです:

/** 
* @param {Array.<{position:Vector2, attraction:Number}>} entities 
*/ 
Agent.prototype.calculateDirectionVector = function(entities){ 
    var agentPosition = this.position; 
    var result = new Vector2(0,0); 

    entities.forEach(function(entity){ 
     //calculate separation between agent and entity 
     var displacement = entity.position.clone().sub(agentPosition); 
     //figure out distance between entities 
     var distance = displacement.length(); 
     //dampen influence of attraction linearly with distance 
     var influence = entity.attraction/distance; 
     //produce force vector exerted by this entity on the agent 
     var force = displacement.normalize().multiplyScalar(influence); 
     //add up forces on the entity 
     result.add(force); 
    }); 

    //normalize the resulting vector 
    result.normalize(); 

    return result; 
} 
+0

すばらしい解決策!どうもありがとう! – Luka967

0

あなたが作成した大きなヒューリスティックですが、このロジックを維持したい場合は、明らかに自分の位置にアクセスできるので、ウイルスに対するデカルト距離を考慮に入れてください。

機能は、あなたがしきい値DIST_MINとシンプルなifを使用するか、遠くのウイルスが角度に与える影響を軽減するためにangle/distance(良い)のような機能を使用することができますBotPlayer.prototype.getDistまたはBotPlayer.prototype.getAccDist

です。

関連する問題