![]() |
Pathfinding mit A*
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mich heute Nachmittag mal drangesetzt und habe versucht den obigen Algorithmus zum Finden eines Pfades zu implementieren. Also so halb funktionieren tut es schon mal. Ich habe mich an die Beschreibung von dieser Seite gehalten:
![]() Nur irgendwie bleibt mein Algorithmus auf halben Weg stecken, das heißt, er landet in einer Endlosschleife. Desweitern, wenn ich das Hindernis bis an die Oberkante des Spielfeldes mache, bleibt er auch stecken. Und ich finde den Fehler in meinem Algorithmus einfach nicht. Ich weiß, dass der Code bestimmt nicht sehr performant ist und auch nicht unbedingt den kürzesten Wg findet, aber ich will überhaupt erstmal einen Weg finden. :-? Ich glaube, hier Sourcecode zu posten ist etwas schlecht, da man es im Zusammenhang sehen muss. Deswegen hänge ich mal den Source an. Ich denke, der Source spricht für sich. |
Re: Pathfinding mit A*
Ich habe jetzt auch den horizontalen Abstand für die geschätzte Entfernung zum Ziel mit einbezogen:
Delphi-Quellcode:
Jetzt hängt er gleich beim ersten mal in einer Endlosschleife. :gruebel:
List.H := (Abs(Abs((Dest.X - i)) + (Abs(Dest.Y - j)))) * 10;
|
Re: Pathfinding mit A*
Ich hatte vor einiger Zeit mal
![]() |
Re: Pathfinding mit A*
@Luckie
Zwar nichts zum Problem, aber warum machst du ein Abs() um die Summe zweier anderer Abs()-gekapselten Rechnungen? Da diese 100% positiv sind und eine Summe zweier positiver Werte sicher nicht negativ ist, ist die äußerste abs() sinnlos ;) air |
Re: Pathfinding mit A*
Wenn ich den Beitrag richtig verstanden habe, habe ich vermutlich den fehler gefunden und evtl. eine lösung für dich(ich habes nicht gestet).
Meiner meinung nach berechnes du den H wert falsch.
Delphi-Quellcode:
Laut tutorial musst du nicht einfach die Horizontale länge bereichnen sondern auch die vertikal damit meine ich folgendes für die Richtung Rechts:
if Dest.X > Start.X then
List.H := (Dest.X - i) * 10 else List.H := (i - Dest.X) * 10;
Delphi-Quellcode:
das müste eigentlich so gehen.
if Dest.X > Start.x then begin
Liste.H:=(Dest.X - i)+Dest.Y-j * 10 end; damit meine ich folgendes: du berechnes vom Start zum Ziel Punkt und berechnes den abstand. Angenommen das Ziel ist unten Rechts und der Start Oben Linx. Dazwischen währen jetzt hindernisse. Jetzt musst du die Horizontale richtung berechnen und anschließnd die Vertiklae richtung und anschließnd zusammen addieren. So habe ich es verstanden. Bin mir aber nicht sicher aber das richtig ist. |
Re: Pathfinding mit A*
Zitat:
Delphi-Quellcode:
Aber er bleibt trotzdem wieder stecken. :evil:
if Dest.X > Start.x then
begin dx := Dest.X - i; end else if Dest.X < Start.X then begin dx := i - Dest.X; end else dx := Dest.X; if Dest.y > Start.y then begin dy := Dest.y - j; end else if Dest.Y < Start.Y then begin dy := j - Dest.y; end else dy := Dest.Y; |
Re: Pathfinding mit A*
Versuchs doch nochmal auf die kurze Weise:
Delphi-Quellcode:
air
List.H := (Abs(Dest.X - i) + Abs(Dest.Y - j)) * 10;
|
Re: Pathfinding mit A*
Habe ich auch schon versucht, das klappt auch nicht. Im obigen Code war ein Fehler. So stimmt es:
Delphi-Quellcode:
Jetzt kommt er bis zum Ziel, aber nur bis ein Kästchen vor das Ziel, so dass er aus der Schleife nicht rauskommt:
if Dest.X > i then
begin dx := Dest.X - i; end else if Dest.X < i then begin dx := i - Dest.X; end else dx := Dest.X; if Dest.y > j then begin dy := Dest.y - j; end else if Dest.Y < j then begin dy := j - Dest.y; end else dy := Dest.Y; List.H := (dx + dy) * 10;
Delphi-Quellcode:
while (Dest.X <> Start.X) or (Dest.Y <> Start.Y) do
begin Application.ProcessMessages; Start := FindPath(Maze, Start, Dest); SetLength(Path, length(Path) + 1); Path[length(Path) - 1] := Start; SetLength(OpenList, 0); Sleep(250); DrawSquare(2, 3, SPACING, clGreen); InvalidateRect(Handle, nil, True); end; |
Re: Pathfinding mit A*
Michael,
versuche mal folgendes in TForm1.Button1Click ersetze
Delphi-Quellcode:
durch
while (Dest.X - 1 <> Start.X) or (Dest.Y - 1 <> Start.Y) do
Delphi-Quellcode:
in FindPath
while (abs(dest.x-start.x)>1) or (abs(dest.y-start.y)>1) do
ersetze
Delphi-Quellcode:
durch
if Dest.X > Start.X then
List.H := (Dest.X - i) * 10 else List.H := (i - Dest.X) * 10; // Diagonale Felder if ((Start.X - 1 = i) and (Start.Y - 1 = j)) // oben links or ((Start.X - 1 = i) and (Start.Y + 1 = j)) // unten links or ((Start.X + 1 = i) and (Start.Y - 1 = j)) // oben rechts or ((Start.X + 1 = i) and (Start.Y + 1 = J)) then // unten rechts List.G := 14 else // alle anderen List.G := 10; List.F := List.G + List.H;
Delphi-Quellcode:
dx und dy mußt Du natürlich lokal deklarieren.
dx:=abs(dest.x-i);
dy:=abs(dest.y-j); list.f:=dx*dx+dy*dy; keine Garantie, aber bei mir funktioniert das. Gruß, Klaus |
Re: Pathfinding mit A*
Hm, danke. Für diese eine Situation scheint es zu klappen. Aber wenn ich das Ziel auf 6,4 versetze oder die Mauer oben zu mache, dann geht es schon nicht mehr. :gruebel:
Im ersten Posting jetzt noch mnal mein aktueller Code. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz