Avevo bisogno di risolvere un problema simile: l'individuazione di percorsi su una grande griglia simile a un labirinto con "costi" e barriere in costante cambiamento.
Il fatto è che nel gioco di difesa della torre il numero di entità che devono risolvere il percorso per loro è di solito molto più grande del numero di nodi nel grafico. Un * non lo è l'algoritmo più appropriato per gestirlo, perché dovrai risolverlo di nuovo ogni volta che qualcosa viene cambiato. Bene, è appropriato se devi trovare solo un percorso, ma nel mio caso avevo bisogno di essere in grado di gestire entità che possono apparire in posizioni diverse e ognuna ha il suo percorso.
L' algoritmo di Floyd-Warshall è molto più appropriato, anche se nel mio caso ho scritto un algoritmo personalizzato che ogni volta che un nodo cambia, ricalcola il costo di quel nodo da tutti i suoi vicini, e quindi se i vicini sono stati cambiati viene invocato ricorsivamente su di loro.
Quindi all'inizio del gioco, accendo questo algoritmo su tutti i miei nodi "obiettivo". Quindi, ogni volta che cambia un singolo nodo (ad esempio, diventa non passabile), lo accendo solo su quel nodo e la modifica viene propagata a tutti i nodi che saranno interessati e quindi interrotta. Quindi non è necessario il ricalcolo globale e l'algoritmo è completamente indipendente dal numero di entità che richiedono l'individuazione del percorso.
Il mio algoritmo era sostanzialmente qualcosa di simile (pseudo-codice):
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()
Con il punteggio iniziale a seconda che il nodo sia un obiettivo o una sorta di barriera.