Rozwój
Programowanie SI
- Dokumentacja API
- Wprowadzenie
- plik info.nut
- plik main.nut
- Podstawy
- Poszukiwacz drogi
- Użycie pathfinder`a kolei
- Zapis / Odczyt danych
- Dobrze wiedzieć
- Squirrel
- Listy
- Poradnik na błędy OTTD
- Trams
- Biblioteki SI
- Forum
- Forum FAQ
- Zachowanie SI
- Użycie krótkich nazw
SIy
Wszystko kategorii NoAI
Contents |
Warunki wstępne
Zanim zadzwonisz do pathfindera, musisz wybrać typ szyny, którego chcesz użyć. Jest to bezpieczny sposób, w jaki Zutty sugeruje wybór pierwszego rodzaju szyny z listy.
local types = AIRailTypeList(); AIRail.SetCurrentRailType(types.Begin());
Inicjalizacja
Podobnie jak w przypadku każdej biblioteki, zanim będzie można jej użyć, należy ją zaimportować. Możesz to zrobić, umieszczając następujący wiersz w górnej części kodu.
import("pathfinder.rail", "RailPathFinder", 1);
Spowoduje to zaimportowanie identyfikatora ścieżki kolejowej w wersji 1 i nadanie mu nazwy RailPathFinder
. Możesz teraz instalizować to jak każdą inną klasę:
local pathfinder = RailPathFinder();
Zanim zaczniesz znajdować trasę, możesz najpierw ustawić niektóre parametry. Dostępne parametry to:
Nazwa | Domyślna wartość | Znaczenie |
---|---|---|
cost.max_cost | 2000000000 | Maksymalny koszt trasy. |
cost.tile | 100 | Koszt toru non-diagonal (nieukośnego) . |
cost.diagonal_tile | 70 | Koszt toru ukośnego. |
cost.turn | 50 | Koszt dodawany do _tile_tile / _cost_diagonal_tile, jeśli kierunek się zmieni. |
cost.slope | 100 | Dodatkowy koszt, jeśli kafel jest nachylony. |
cost.bridge_per_tile | 150 | Koszt za kafel nowego mostu jest dodawany do _cost_tile. |
cost.tunnel_per_tile | 120 | Koszt na kafel nowego tunelu jest dodawany do _cost_tile. |
cost.coast | 20 | Dodatkowy koszt za płytkę wybrzeża. |
cost.max_bridge_length | 6 | Maksymalna długość mostu, który zostanie zbudowany. |
cost.max_tunnel_length | 6 | Maksymalna długość tunelu, który zostanie zbudowany. |
Aby ustawić parametr, wystarczy użyć:
pathfinder.cost.tile = 100;
Planowanie trasy
Tak więc, teraz wiemy, jak stworzyć instancję pathfindera i ustawić funkcje kosztów, nadszedł czas, aby tę wiedzę wykorzystać. Zaplanujmy naszą pierwszą linię kolejową. Najpierw potrzebujemy jednego (lub więcej) kafelków źródła i jednego (lub więcej) kafelków celu. Na razie załóżmy, że już je mamy, ponieważ wykraczanie poza zakres tej strony wyjaśnia, jak je zdobyć. Powiedzmy na przykład, że chcemy zbudować szynę między dwiema stacjami st_a i st_b. W tym przykładzie założymy, że kierunek stacji to NE_SW i chcemy połączyć stronę NE stacji. Najpierw wywołujemy InitializePath
na naszym obiekcie pathfinder:
local tile_a = AIStation.GetLocation(st_a); local tile_b = AIStation.GetLocation(st_b); pathfinder.InitializePath([[tile_a, tile_a + AIMap.GetTileIndex(-1, 0)]], [[tile_b + AIMap.GetTileIndex(-1, 0), tile_b]]);
Pathfinder oczekuje tablicy tablic [start_tile, tile_before_start] -arrays i tablicy [last_tile, tile_after_end] -arrays. ponieważ mamy tylko jedno źródło i jedną płytkę celu, po prostu utworzymy dwie tablice z jednym elementem. Teraz pathfinder jest gotowy do znalezienia ścieżki.
local path = pathfinder.FindPath(-1);
Parametr FindPath
accepts to liczba iteracji, które powinien wykonać przed zwróceniem. -1 oznacza zapętlenie aż do znalezienia ścieżki. Po zakończeniu zwraca albo znalezioną ścieżkę, albo zero, aby wskazać, że nie istnieje żadna trasa.
Budowanie zaplanowanej trasy
Załóżmy, że pathfinder zwrócił ścieżkę, jak zacząć ją budować? Na początek miło jest wiedzieć, że FindPath
zwraca instancję klasy AyStar.Path
. Aby wyświetlić dokumentację, otwórz bin/ai/library/graph/aystar/main.nut
. Zasadniczo ma trzy funkcje: GetParent()
, GetCost()
i GetTile()
. GetCost()
na razie nie jest użyteczny, więc użyjemy po prostu GetParent()
i GetTile()
. Aby zbudować trasę znalezioną przez pathfinder, wywołujemy path.GetParent()
, aż zwróci null. Ponieważ pathfinder może również zwracać mosty / tunele, musimy sprawdzić odległość między bieżącym węzłem a poprzednim węzłem. Jeśli ta odległość jest większa niż 1, powinniśmy zbudować most / tunel .
local prev = null; local prevprev = null; while (path != null) { if (prevprev != null) { if (AIMap.DistanceManhattan(prev, path.GetTile()) > 1) { if (AITunnel.GetOtherTunnelEnd(prev) == path.GetTile()) { AITunnel.BuildTunnel(AIVehicle.VT_RAIL, prev); } else { local bridge_list = AIBridgeList_Length(AIMap.DistanceManhattan(path.GetTile(), prev) + 1); bridge_list.Valuate(AIBridge.GetMaxSpeed); bridge_list.Sort(AIList.SORT_BY_VALUE, false); AIBridge.BuildBridge(AIVehicle.VT_RAIL, bridge_list.Begin(), prev, path.GetTile()); } prevprev = prev; prev = path.GetTile(); path = path.GetParent(); } else { AIRail.BuildRail(prevprev, prev, path.GetTile()); } } if (path != null) { prevprev = prev; prev = path.GetTile(); path = path.GetParent(); } }
Ten kod zapętla się na całej trasie. Dla każdego elementu próbuje zbudować most / tunel lub kawałek szyny. Pamiętaj, że w prawdziwej sztucznej inteligencji prawdopodobnie będziesz chciał sprawdzić, czy AIRail.BuildRail
zwraca true, a jeśli nie, ponownie uruchom wyszukiwanie ścieżki.