Quelques idées pour éviter les recherches qui aboutissent à des chemins échoués:
ID de l'île
L'une des façons les moins chères de terminer efficacement les recherches A * plus rapidement est de ne faire aucune recherche. Si les zones sont vraiment infranchissables par tous les agents, inondez chaque zone avec un identifiant d'îlot unique en charge (ou dans le pipeline). Lors de la recherche de chemin, vérifiez si l' ID d'îlot de l'origine du chemin correspond à l' ID d'îlot de la destination. S'ils ne correspondent pas, la recherche est inutile - les deux points se trouvent sur des îles distinctes et non connectées. Cela n'aide que s'il existe des nœuds vraiment infranchissables pour tous les agents.
Limite de la limite supérieure
Je limite la limite supérieure du nombre maximal de nœuds pouvant être recherchés. Cela aide les recherches infranchissables à s'exécuter pour toujours, mais cela signifie que certaines recherches passables qui sont très longues peuvent être perdues. Ce nombre doit être réglé, et il ne résout pas vraiment le problème, mais il atténue les coûts associés aux longues recherches.
Si vous constatez que cela prend trop de temps, les techniques suivantes sont utiles:
Rendre les itérations asynchrones et limites
Laissez la recherche s'exécuter dans un thread séparé ou un peu à chaque image afin que le jeu ne s'arrête pas en attendant la recherche. Affichez une animation représentant un personnage se grattant la tête ou tapant des pieds, ou tout ce qui est approprié en attendant la fin de la recherche. Pour ce faire efficacement, je garderais l'état de la recherche en tant qu'objet séparé et permettrait à plusieurs états d'exister. Lorsqu'un chemin est demandé, saisissez un objet d'état libre et ajoutez-le à la file d'attente des objets d'état actifs. Dans votre mise à jour d'orientation, retirez l'élément actif de l'avant de la file d'attente et exécutez A * jusqu'à ce que A. soit terminé ou B. une certaine limite d'itérations soit exécutée. S'il est terminé, remettez l'objet d'état dans la liste des objets d'état libres. S'il n'est pas terminé, mettez-le à la fin des «recherches actives» et passez à la suivante.
Choisissez les bonnes structures de données
Assurez-vous d'utiliser les bonnes structures de données. Voici comment fonctionne mon StateObject. Tous mes nœuds sont pré-alloués à un nombre fini - disons 1024 ou 2048 - pour des raisons de performances. J'utilise un pool de nœuds qui accélère l'allocation des nœuds et cela me permet également de stocker des index au lieu de pointeurs dans mes structures de données qui sont des u16 (ou u8 si j'ai 255 nœuds max, ce que je fais sur certains jeux). Pour mon identification, j'utilise une file d'attente prioritaire pour la liste ouverte, stockant des pointeurs vers des objets Node. Il est implémenté comme un tas binaire, et je trie les valeurs à virgule flottante sous forme d'entiers car elles sont toujours positives et ma plateforme a des comparaisons à virgule flottante lentes. J'utilise une table de hachage pour ma carte fermée pour garder une trace des nœuds que j'ai visités. Il stocke les NodeIDs, pas les Nodes, pour économiser sur les tailles de cache.
Cachez ce que vous pouvez
Lorsque vous visitez un nœud pour la première fois et calculez la distance jusqu'à la destination, mettez-le en cache dans le nœud stocké dans l'objet État. Si vous revisitez le nœud, utilisez le résultat mis en cache au lieu de le calculer à nouveau. Dans mon cas, cela évite d'avoir à faire une racine carrée sur des nœuds revisités. Vous pouvez trouver qu'il existe d'autres valeurs que vous pouvez précalculer et mettre en cache.
D'autres domaines que vous pourriez étudier: utilisez la recherche de chemin bidirectionnelle pour rechercher à partir de l'une ou l'autre extrémité. Je ne l'ai pas fait, mais comme d'autres l'ont noté, cela pourrait aider, mais ce n'est pas sans mises en garde. L'autre chose sur ma liste à essayer est la recherche de chemin hiérarchique ou la recherche de chemin de clustering. Il existe une description intéressante dans la documentation HavokAI décrivant ici leur concept de clustering, qui est différent des implémentations HPA * décrites ici .
Bonne chance et dites-nous ce que vous trouvez.