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