2016-03-21 8 views
1

Ich mache einen Bot für ein Projekt namens Ogar, eine Agar.io Server-Implementierung in Node.js geschrieben.Berechnen Sie den Winkel zum Kreis mit Vermeidung von Hindernissen

Dieser Bot hat ein Hindernis, eine grüne stachelige Zelle namens Virus (siehe Abbildung). Ich muss diesen Bot programmieren, um dieses Hindernis zu vermeiden, aber ich habe kein Glück. Da es viele Ziele wie in der Abbildung gibt, basiert es auf Updates.

Illustration of what I want

Hier ist der Code, den ich mit bisher endete.

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; 
}; 

Das funktioniert in den meisten Fällen, aber der Bot manchmal völlig ignoriert das Hindernis (this.collisionFromList(cell, this.obstacles); ist völlig in Ordnung) und endet buchstäblich durch sie gehen (explodieren in eine Menge von Zellen).

BotPlayer.prototype hat viele nützliche Funktionen für diese Art von Berechnungen. Siehe this link.

Ich brauche keine Pfadfinderei, nur diese einfache Maßnahme zu vermeiden.

+0

Wenn es drei in gleichem Abstand Hindernisse und bot zur Mitte Hindernis zusteuert, würde nicht den Winkel, dass Ihr den Bot in Richtung der Mitte Hindernis in Gang halten Berechnung ? –

Antwort

1

Es gibt einen alternativen Ansatz zu dem, was Sie versuchen zu tun. Der Ansatz besteht darin, Attraktoren zu verwenden, um Entitäten in Ihrem System zu beschreiben. Ihr "Bot" ist der agent, er hat eine Position und er weiß über andere Entitäten in der Welt und deren Anziehungskraft Bescheid. Sagen Sie, Ihr Ziel hat Kraft und Hindernisse haben -X attraction Kraft, effektiv die "Bot" (agent) abstoßen.

Hier ist eine Entscheidung Pseudo-Code:

/** 
* @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

Eine tolle Lösung! Danke vielmals! – Luka967

0

Es ist eine große Heuristik, die Sie gemacht haben, aber wenn Sie bei dieser Logik bleiben wollen, dann überlegen Sie, die kartesische Distanz zu den Viren zu berücksichtigen, da Sie anscheinend Zugriff auf ihre Position haben.

Die Funktion ist BotPlayer.prototype.getDist oder BotPlayer.prototype.getAccDist

Sie einen Schwellenwert verwenden können DIST_MIN und eine einfache if oder eine Funktion wie angle/distance (besser) verwenden, um die Auswirkungen der entfernten Viren auf den Winkel haben zu verringern.

Verwandte Themen