SI:RailPathfinder/Pl

From OpenTTD
Jump to: navigation, search


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(AIAbstractList.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.

Personal tools