Musiałem rozwiązać podobny problem: znalezienie ścieżki na dużej siatce przypominającej labirynt ze stale zmieniającymi się „kosztami” i barierami.
Chodzi o to, że w grze typu tower defense liczba podmiotów, które muszą mieć dla nich rozwiązaną ścieżkę, jest zwykle znacznie większa niż liczba węzłów na wykresie. * Nie jest najodpowiedniejszym algorytmem do obsługi tego, ponieważ będziesz musiał go rozwiązać od nowa za każdym razem, gdy coś zostanie zmienione. Dobrze jest, jeśli chcesz znaleźć tylko jedną ścieżkę, ale w moim przypadku musiałem być w stanie obsłużyć byty, które mogą pojawiać się w różnych lokalizacjach, a każda z nich ma swoją własną ścieżkę.
Floyd-Warshall algorytm jest bardziej właściwe, choć na moim przypadku Napisałem algorytm niestandardowy że gdy zmiany węzłowe, to ponownie oblicza koszt dla tego węzła z wszystkimi sąsiadami, a następnie , jeśli sąsiedzi zostały zmienione to jest wywoływany rekurencyjnie na nich.
Tak więc na początku gry odpalam ten algorytm na wszystkich moich węzłach „celowych”. Następnie, za każdym razem, gdy zmienia się pojedynczy węzeł (na przykład staje się nie do przejścia), po prostu odpalam go w tym węźle, a zmiana jest propagowana do wszystkich węzłów, które zostaną zmienione, a następnie zatrzymana. Nie ma więc potrzeby globalnego ponownego obliczania, a algorytm jest całkowicie niezależny od liczby jednostek, które będą wymagać szukania ścieżki.
Mój algorytm był w zasadzie czymś w rodzaju (pseudo-kod):
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()
Z początkowym wynikiem zależy od tego, czy węzeł jest celem, czy jakąś barierą.