J'implémente un algorithme multi-agent A * sur une carte de tuiles. Les agents se déplacent uniquement sur les axes X et Y. J'évite les collisions entre eux en vérifiant où se trouvent les autres lors du calcul des chemins.
Cela fonctionne bien, sauf dans le cas où les agents doivent passer la même tuile de différentes directions. Dans des situations comme celle-ci, une solution optimale serait qu'un agent attende que l'autre passe:
De plus, s'il n'y a pas de couloir nord, la recherche de chemin échoue.
Comment pourrais-je implémenter un tel algorithme?
collision-detection
ai
path-finding
Krzysztof Antoniak
la source
la source
Réponses:
Vous pouvez commencer par laisser l'échec de la recherche de chemin. En cas d'échec, choisissez une heure aléatoire dans le futur pour réessayer la recherche de chemin. Certains protocoles de mise en réseau de bas niveau fonctionnent de cette façon , et très bien. Ce que vous devez faire est de construire des chemins un à la fois et de marquer comme utilisés toutes les tuiles qu'un agent traversera. Lorsque d'autres chemins échouent, le temporisateur aléatoire pour redémarrer aidera à répartir les nouvelles recherches de chemin et à rompre les échecs de boucle.
La deuxième partie de votre problème pourrait être gérée en renvoyant deux chemins. Le premier chemin est le retour régulier, même s'il échoue d'un bloc. Le deuxième chemin est un chemin qui ignore complètement tous les agents. Vous pouvez ensuite utiliser les connaissances acquises à partir de ces deux voies pour décider si attendre ou prendre le long chemin serait mieux. L'heuristique de cette décision demandera du travail, mais c'est mieux que de ne rien essayer du tout.
Dans le très mauvais cas où vos agents sont souvent bloqués par des couloirs à largeur unique comme celui-ci, vous devrez peut-être ajouter des endroits sûrs où les agents peuvent rapidement se diriger et attendre que leur véritable chemin s'ouvre (de sorte que l'agent ne attendez et bloquez un couloir).
la source
Plutôt que de résoudre votre problème, voici un moyen de prendre les citrons et de faire de la limonade.
Il y a de nombreuses années, un de mes amis travaillait sur un FPS très connu qui avait précisément le problème que vous décrivez: une zone contrainte aurait un certain nombre de caractères AI qui avaient des positions souhaitées particulières, et l'algorithme de recherche de chemin les bousculait constamment dans l'autre. En particulier, le joueur lancerait, par exemple, une grenade dans une petite pièce remplie d'ennemis, et les personnages de l'IA dans la zone essaieraient chacun de courir jusqu'à leur sortie, mais se rencontreraient et finiraient par s'arrêter, se retourner, frapper quelqu'un d'autre, se retourner, etc. Cela semble très irréaliste.
Les tentatives de création d'un meilleur algorithme de recherche de chemin qui pourraient s'exécuter avec succès étant donné le budget de calcul serré ont échoué. Donc, au lieu de résoudre le problème de la recherche de chemin, mon ami a ajouté un chèque très bon marché à l'IA: si une IA est tombée sur une autre IA deux fois en peu de temps, arrêtez d'essayer de trouver la sortie et à la place, mettez-vous à couvert. Alors maintenant, ce qui se passe, le PC lobe la grenade et voit un tas d'ennemis courir vers les sorties. Ceux qui se heurtent se retournent et on dirait qu'ils se rendent compte qu'ils ne peuvent pas sortir, alors ils se penchent et se couvrent la tête juste avant de sauter. C'est à la fois réaliste et très satisfaisant pour le joueur.
Existe-t-il un moyen similaire de transformer l'inconvénient de votre algorithme générateur de collisions et de le transformer en avantage?
la source
Je trouve généralement préférable d'augmenter le cheminement A * avec d'autres formes de recherche de chemin pour d'autres scénarios localisés; l'évitement des unités en fait généralement partie, en particulier dans un monde où plusieurs agents se déplacent simultanément et créent ainsi des bloqueurs dynamiques).
Généralement, une technique de suivi de bord peut fonctionner pour cela. Lorsque vous suivez un chemin et rencontrez un bloqueur qui ne faisait pas partie du calcul de chemin d'origine, vous choisissez essentiellement une direction (dans le sens horaire ou antihoraire) et essayez de traverser le bloqueur en le parcourant dans cette direction. Si vous ne le pouvez pas, vous attendez que le bloqueur se résout (bien que cela puisse entraîner un blocage).
Vous pouvez également implémenter la possibilité pour les unités de se déplacer en coopération; c'est-à-dire qu'une unité peut demander à une autre unité de s'écarter légèrement pour pouvoir "passer" l'unité bloquante. Cela ne fonctionne pas bien dans un jeu basé sur des tuiles où vous êtes limité au mouvement basé sur des tuiles, car vous pouvez toujours bloquer dans des couloirs à largeur unique comme votre exemple. Dans ce cas, vous pouvez prévoir que les unités se demandent mutuellement de «changer de place», ce qui entraîne la résolution la plupart du temps. Parfois, cela conduit à des unités qui se dépassent, cependant.
"L'évitement d'unité" est un sujet assez courant lorsque l'on parle de pathfinding dans les jeux, il y a beaucoup de succès là-bas. En particulier , vous pouvez consulter cette question sur le « champ d'écoulement » pathfinding utilisé dans Supreme Commander 2. RTSs habituellement courir dans ce problème un grand nombre et le résoudre dans toutes sortes de façons intéressantes.
la source
Si vous avez un système de mouvement basé sur les virages et les virages, vous pouvez créer un graphique 3D où chaque transition déplace l'agent vers l'apparence future de la carte. Demandez ensuite à chaque agent de réclamer les tuiles sur lesquelles il se trouverait à l'avenir et de les marquer comme inaccessibles. Chaque agent dispose alors d'une option supplémentaire de "attente" jusqu'à la case à cocher suivante comme troisième moyen de transition dans le graphique. Cela sera plus difficile sur votre système mais devrait vous donner de meilleurs résultats que d'attendre au hasard. Encore mieux si vous autorisez 2 agents à communiquer bt en demandant à l'un d'eux d'envoyer un message "Je veux vous passer" si le chemin le plus court passe par cet agent,
la source
Lorsque vous utilisez un algorithme comme A *, vous avez la plus grande latitude pour travailler avec l'heuristique de coût.
Dans ce cas particulier, vous pouvez ajuster l'heuristique pour augmenter le coût des mouvements qui amènent un agent près d'un autre agent, le problème est que vous vous retrouverez probablement tous les deux à essayer de prendre la route supérieure, et vous pourriez vous retrouver avec des oscillations d'avant en arrière entre les chemins lorsqu'ils se ferment les uns les autres selon le moment exact.
Une autre possibilité consiste à suivre les itinéraires prévus par les agents et à ajuster les coûts à la hausse le long des chemins prévus par les autres agents. Cela permet aux agents de se coordonner efficacement dans une mesure limitée. Le problème principal ici est de savoir si toutes les routes sont bloquées. La recherche de chemin peut continuer à échouer selon le dernier déplacement de l'agent.
Dans le cas où il n'y a qu'un seul chemin, la recherche de chemin échouera ou avancera l'une sur l'autre jusqu'à ce qu'elle se bloque.
Si aucun de ces éléments n'est suffisant, vous devez également commencer à suivre le temps lors du calcul de vos coûts. Le coût pour le deuxième agent devrait être le temps qu'il faut au premier agent pour se clarifier, plus le coût de traversée normal, de cette manière, votre agent serait en mesure de décider correctement quand attendre par rapport à prendre l'autre chemin.
Prendre le calendrier en accord peut représenter beaucoup plus d'efforts, de sorte que la plupart des gens se contentent de modifier la disposition des niveaux et les valeurs de coût jusqu'à ce que les choses soient suffisamment bonnes.
la source
Normalement, je vous conseillerais d'utiliser des comportements de pilotage pour résoudre des problèmes comme celui-ci lors du suivi de chemin. Et vous pourriez encore en prendre beaucoup pour vous inspirer pour grouper les comportements. Mais malheureusement, il n'est pas vraiment directement applicable pour un mouvement simple basé sur des carreaux.
Étant donné que vous disposez déjà d'un système anticollision efficace pour la plupart des situations, concentrons-nous sur celui-ci en particulier. Je suppose que vous refaites le chemin à chaque fois qu'un agent veut se déplacer, sinon je ne vois pas comment ils réagissent aux autres se déplaçant pendant leur déplacement. Deuxièmement, je suppose que ces agents sont amicaux entre eux.
Vous proposez un agent en attente de l'autre et je vous conseille de faire exactement cela. Donnez aux agents un moyen d'accéder aux chemins des autres, recherchez la première tuile de votre propre chemin qui ne fait pas partie de l'autre chemin et allez-y. Les problèmes avec cette technique peuvent être:
Comment décidez-vous s'il existe un autre moyen acceptable de contourner l'autre agent ou non? Vous ne voulez pas attendre l'autre agent s'il y a suffisamment d'espace pour le contourner. Un échec de recherche de chemin lors de l'examen de l'autre agent est un signe clair de la situation que vous souhaitez résoudre, mais dans l'exemple que vous avez évoqué, il n'y aura pas d'échec de recherche de chemin. Mais vous pouvez - avec un peu de calcul - décider si le chemin alternatif A * que vous donne contourne simplement l'autre agent dans un petit cercle, ou utilise un chemin totalement différent comme le couloir nord.
Je ne sais pas jusqu'où un agent peut voyager pendant un tour / opération, mais si ce n'est pas assez loin, ou si tous les agents se déplacent parallèlement, les deux agents décideraient d'attendre à l'autre bout du chemin. Cela peut être corrigé en signalant à l'autre agent que vous libérez son chemin.
la source
L'une des solutions possibles consisterait à désactiver la collision d'unités dans ces endroits restreints.
Par exemple, dans le jeu Starcraft, les ouvriers (SCV, sondes, drones) n'entrent pas en collision lorsqu'ils extraient des cristaux.
la source