Seminararbeit: 3D-Pathfinding – Ausarbeitung

Werbung
Seminararbeit: 3D-Pathfinding – Ausarbeitung
Johannes Schlicker
Bereits zu Beginn der Entwicklung von Computersoftware versuchte man künstliche Intelligenz zu
erzeugen. Ein Teil dieser künstlichen Intelligenz, welcher bis heute wohl am besten in Software
umsetzbar ist, ist die Pfadfindung. Speziell für Computerspiele braucht man dieses Wissen vor allem
im zwei- und dreidimensionalen Raum.
Das Ziel eines Algorithmus zur Pfadfindung ist es, von einem Punkt A zu einem zweiten Punkt B zu
gelangen. Dieser Weg muss dabei bestimmten Ansprüchen genügen, wie beispielsweise, dass er nicht
beliebig sein darf, sondern der kürzeste oder schnellste. Ein weiteres Augenmerk muss natürlich auch
auf den Algorithmus gelegt werden, der möglichst effizient und ressourcensparend arbeiten soll. In
Computerspielen treten dabei auch noch andere Probleme auf, wie die Koordination mehrerer
computergesteuerter Einheiten. Immer wichtiger in neuerer Spielesoftware wird außerdem eine
ruckelfreie, flüssige Animation. Wie in vielen anderen Bereichen der Computertechnik gilt auch hier:
Je mehr Ressourcen zur Verfügung stehen, desto komplexer können algorithmische Abläufe sein.
Historisch betrachtet ist das allseits bekannte Pacman das erste Spiel, bei dem ein
Pfadfindungsalgorithmus zum Einsatz kam. Pacman ist eine gelbe Spielfigur, die der Spieler durch ein
Labyrinth bewegen und dabei Geistern ausweichen muss, die vom Computer gesteuert werden und
versuchen den Pacman zu fressen. Diese vier Geister folgen jeder einem anderen Algorithmus, der
sie auf mehr oder weniger gutem Weg zur Spielerfigur leitet. Während sich die ersten drei Geister
noch relativ unbeholfen durch das Labyrinth bewegen, folgt der vierte Geist bereits einem
trickreichen Algorithmus: An fast jeder Kreuzung im Labyrinth hat der Geist die Wahl nach links,
rechts oder geradeaus weiterzugehen. Der Algorithmus berechnet nun einen wahrscheinlichen Weg,
den der Pacman begehen wird und versucht dann durch die richtige Wahl seines weiteren Weges
den Weg des Spielers zu kreuzen, um ihm so immer näher zu kommen.
Ein weiterer Klassiker aus dem Spielsoftwarebereich ist das Strategiespiel Age of Empires. In diesem
Spiel müssen schon ganze Armeen koordiniert werden. Der Algorithmus, der dies bewerkstelligt
nimmt bereits 70% der benötigten Rechenleistung des Spiels ein.
Wie bei den beiden eben genannten Beispielen, basiert auch der erste Teil der Doom-Reihe auf
Pfadfindung im zweidimensionalen Raum. Auch wenn man sich bei Doom 1 bereits auf mehreren
Ebenen bewegen kann, können die Algorithmen auf nur einer Fläche rechnen, da sich die scheinbar
dreidimensionalen Ebenen niemals überschneiden und somit Spielfiguren nicht übereinander stehen
oder gehen können.
Auch heute wird die Wegfindung in Computerspielen noch größtenteils auf zwei Dimensionen
zurückgeführt, allerdings wurden in den letzten Jahren die Methoden verfeinert und die Erwartungen
der Endnutzer steigen immer weiter. Dadurch ergibt sich ein sehr großer Rechenaufwand. Dieser
wird bei Spielen wie Counterstrike oder Bioshock minimiert, indem Wegpunkte eingesetzt werden,
um die Menge der möglichen Wege, die ein Algorithmus berechnen müsste möglichst klein zu halten.
Als Programmiergrundlage für den Pathfinding Algorithmus dient die Engine von Spielen, da von
dieser aus auf viele verschiedene andere Aspekte eins Spiels zugegriffen werden kann. Man erkennt
auch sofort, dass es keine perfekte Variante für alles gibt. So ist es in einem Strategiespiel die
Aufgabe der Engine möglichst viele Einheiten zu bewegen, wobei das Hauptaugenmerk auf der
Koordination liegt. Hingegen bei einem Egoshooter kommt es schon mehr auf Feinheiten an, wie
beispielsweise die möglichst kürzesten und sichersten Wege zu finden. Man muss also die
Algorithmen den Ansprüchen genügend entwickeln und kann sich nicht immer auf die gleichen
Methoden verlassen.
Es gibt mehrere Möglichkeiten, sich die Arbeit zu vereinfachen. Eine bereits genannte sind
Wegpunkte. Hierbei handelt es sich um ein Netz von miteinander verbundenen Punkten, das die
Karte überzieht und welches dazu dient, die fast endlose Menge an begehbaren Punkten zu
minimieren um somit Ressourcen zu sparen. Man kann sich die Karte dann auch als Graph vorstellen,
auf dem der Algorithmus arbeitet.
Ein weiterer Trick der angewandt wird, um die dritte Dimension zur Wegberechnung auszublenden,
ist Wegpunkte, die auf Steigungen oder Gefällen liegen zu werten, indem man ihnen Zahlenwerte
zuweist. Der Algorithmus weiß dadurch, dass zum Beispiel der Weg von A nach B über den Berg zwar
kürzer ist, aber langsamer, ohne dazu Berechnungen in der dritten Dimension machen zu müssen.
Man muss für einen guten Algorithmus ein Gleichgewicht zwischen Genauigkeit und Effizienz finden.
Es gibt unabhängig von Vereinfachungen mehrere Algorithmen zum Berechnen von Pfaden. Der
rechenaufwendigste, aber genaueste ist der Brute-Force-Algorithmus. Dieser geht von jedem Punkt
aus zu allen benachbarten und speichert den bisher zurückgelegten Weg. Dieser Schritt wird so oft
wiederholt, bis alle Punkte auf der Karte erreicht sind. Dann wird der kürzeste gespeicherte Weg von
Punkt A nach B als Ergebnispfad ausgegeben.
Der Dijkstra-Algorithmus geht bereits effizienter vor. Es wird ein Startknoten gewählt und von diesem
dann der kürzeste Weg zu einem Nachbarknoten. Dieser Vorgang wird so oft wiederholt, bis man den
Zielknoten erreicht hat und alle anderen getesteten Wege länger sind. Dabei wird allerdings nicht
von den neu hinzugefügten Knoten weitergerechnet, sondern Ausgangspunkt ist immer der
Startknoten und als Wegkosten gilt immer die Entfernung zwischen Startknoten und aktuellem
letzten Knoten eines Pfades über alle Zwischenknoten. Die Zeitkomplexität beläuft sich bei Dijkstras
Algorithmus nur auf n log n.
Der heute am meisten angewandte Algorithmus ist jedoch der A-Stern-Algorithmus. Er ist nahe
verwandt mit dem von Dijkstra, aber es kommt eine entscheidende Komponente hinzu. Es wird nicht
nur der bisher begangene Weg auf Länge geprüft, sondern es wird zum bereits zurückgelegten Weg
noch eine Variable hinzuaddiert, die den Restweg schätzt. Aus der Liste der geschätzten Gesamtwege
wird dann der kürzeste herausgenommen und bis zum nächsten Knoten genau berechnet. Dies führt
uns zu standardisierten Bezeichnungen für den A-Stern-Algorithmus. Es gibt eine offene Liste, in der
alle noch nicht ausgewerteten Nachbarknoten aller ausgewerteten Knoten stehen. Die geschlossene
Liste beinhaltet dagegen alle bereits ausgewerteten Knoten. Als G bezeichnet man die berechneten
Wegkosten vom Startknoten zum aktuellen Knoten. H ist eine Heuristik zur Schätzung der
Restwegkosten bis zum Zielknoten, die nur einer Regel folgen muss, welche besagt, dass die
Schätzung niemals größer sein darf als der echte Weg. Addiert man G und H so erhält man F, was die
geschätzten minimalen Gesamtwegkosten bezeichnet.
Im Folgenden soll kurz die Funktion des bis heute effektivsten Wegfindungsalgorithmus dargestellt
werden. Der erste Schritt besteht darin, den Startknoten in die offene List einzufügen. Danach
beginnt eine Schleife, die den Kern des A-Stern-Algorithmus darstellt. Man wählt immer den Knoten
mit dem kleinsten F aus der offenen Liste und verschiebt diesen in die geschlossene Liste, also in die
Liste der bearbeiteten Knoten. Ist die offene Liste leer und der Zielknoten nicht in der geschlossenen
Liste, so gibt es keine Pfad zum Ziel. Wenn der Zielknoten allerdings in der geschlossenen Liste ist, so
terminiert die Schleife, weil der kürzeste Weg gefunden wurde. Sofern sie nicht in der geschlossenen
Liste sind, werden nun alle Nachfolgeknoten des eben verschobenen in die offene Liste eingefügt. Für
diese wird nun ihr jeweiliges F berechnet. Das ist also die Summe aus der eben begangenen Kante
plus die bis zum Anfang dieser Kante zurückgelegten Wegkosten plus die Restwegschätzung H. Ist
dieser Nachfolgeknoten bereits auf der offenen Liste und die Gesamtwegkosten F höher als die alten
für diesen Knoten berechneten, geschieht nichts. Sind die Kosten jedoch geringer, so wird der neue
Pfad zu diesem Knoten über den aktuellen Knoten gesetzt. Dieses Vorgehen wird so lange
wiederholt, bis eine der oben genannten Terminierungsbedingungen eintrifft und der perfekte Weg
gefunden wurde.
Die Zeitkomplexität des A-Stern-Algorithmus ist stark abhängig von der Heuristik zur
Restwegschätzung. Erfüllt diese jedoch die Vorgabe des monotonen Verhaltens, so ergibt sich eine
Zeitkomplexität von n log n. In der Realität werden allerdings weitaus weniger Schritte benötigt, als
bei Dijkstras Algorithmus auf derselben Graphenvorlage. Ein weiteres zeitaufwendiges Problem stellt
bei großen Datenmengen das Management der offenen Liste dar. Die Zeitkosten dafür können
allerdings ebenfalls minimiert werden, indem man die offene Liste als Binär-Heap realisiert.
Da der Algorithmus immer die Wahl zugunsten des kürzesten Weges trifft und nicht auf eine schöne
Strecke achtet, wendet man einen kleinen Trick an: Am Beispiel des A-Stern Algorithmus wird immer
dann, wenn ein Knick im Weg entstehen soll der Wert von G minimal erhöht, damit bei einer
möglichen Auswahl von gleich langen Wegen immer der mit den wenigsten Knicken gewählt wird.
Nachdem der kürzeste Weg vom Algorithmus berechnet wurde gibt es allerdings immer noch
Verbesserungsmöglichkeiten für den Pfad von A nach B. Wie oben erwähnt vermeidet der
Algorithmus Knicke im Weg. Allerdings ist es nicht möglich ohne sie auszukommen. Um das Aussehen
zu verbessern und um schönere Animationen der Einheiten die den Weg beschreiten zu
gewährleisten, wird durch dem Algorithmus nachgeschaltet Programme der Weg zum Beispiel
abgerundet, indem der Pfad durch eine Kurve angenähert wird.
Heutige Rechensysteme stellen diese Berechnungen in wenigen Sekundenbruchteilen an. Ist die
Berechnung abgeschlossen wird der Pfad an die Engine übergeben, die dann Einheiten auf diesem
bewegt.
Quellen:
1. http://www.policyalmanac.org/games/aStarTutorial_de.html
2. http://de.wikipedia.org/wiki/Pathfinding
3. http://de.wikipedia.org/wiki/A%2A-Algorithmus
Herunterladen