J'avais besoin de résoudre un problème similaire: trouver la voie sur une grande grille semblable à un labyrinthe avec des «coûts» et des obstacles en constante évolution.
Le fait est que, dans le jeu de tower defense, le nombre d'entités qui ont besoin que le chemin soit résolu pour elles est généralement beaucoup plus grand que le nombre de nœuds dans le graphique. Un * n'est pas l'algorithme le plus approprié pour gérer cela, car vous devrez le résoudre à nouveau chaque fois que quelque chose est modifié. Eh bien, c'est approprié si vous devez trouver un seul chemin, mais dans mon cas, je devais être capable de gérer des entités qui peuvent apparaître à différents endroits et chacune a son propre chemin.
L' algorithme Floyd-Warshall est beaucoup plus approprié, mais pour mon cas, j'ai écrit un algorithme personnalisé qui chaque fois qu'un nœud change, il recalcule le coût pour ce nœud à partir de tous ses voisins, puis si les voisins ont été modifiés, il est invoqué récursivement sur eux.
Donc, au début du jeu, je lance simplement cet algorithme sur tous mes nœuds "objectif". Ensuite, chaque fois qu'un seul nœud change (par exemple, devient impossible à passer), je le lance simplement sur ce nœud et le changement est propagé à tous les nœuds qui seront affectés, puis arrêté. Donc, pas besoin de recalcul global, et l'algorithme est complètement indépendant du nombre d'entités qui nécessiteront la recherche de chemin.
Mon algorithme était essentiellement quelque chose comme (pseudo-code):
update_node method in Node class:
$old <- $my_score
find $neighbor node among all neighbors such that
$neighbor.score + distance_to($neighbor) is minimal
$my_score <- $neighbor.score + distance_to($neighbor)
$next_node <- $neighbor
if ($my_score != $old)
for each $neighbor
$neighbor.update_node()
Avec le score initial selon que le nœud est une cible ou une sorte de barrière.