Thema: Künstliche Intelligenz in Computerspielen: Ein regelbasiertes System für ein Jump N Run Computerspiel Bachelorarbeit im Studiengang Angewandte Informatik der Fakultät Wirtschaftsinformatik und Angewandte Informatik der Otto-Friedrich-Universität Bamberg Verfasser: Frederic Ehmann Gutachter: Ute Schmid Zusammenfassung In dieser Bachelorarbeit geht es um die Entwicklung eines regelbasierten Systems mit dynamischer Prioritätszuweisung für ein selbst kreiertes Jump N Run Computerspiel. Hierbei werden Faustregeln definiert, nach denen gehandelt werden soll. Diese Regeln müssen gewisse Vorbedingungen erfüllen, um angewandt werden zu können. Das System entscheidet dann, je nach Priorität, welche Regel anzuwenden ist. Die Priorität kann von verschiedenen Werten abhängen. Es wurden auch Regeln erstellt, bei denen es nötig ist, Wege zu planen. Dazu überführt man den Zustand des Spieles in einen Graphen. Normalerweise kann man den Graphen in der Leveldesignphase manuell definieren. Doch das Spiel enthält zufällig kreierte Levels, was es nötig macht, die Graphen für die Wegfindung automatisch erstellen zu lassen. Hierfür werden mehrere Ansätze der automatischen Graphenerstellung durch geometrische Analyse vorgestellt. Es hat sich jedoch herausgestellt, dass die Benutzung der Regeln mit Wegfindung meist die Ergebnisse verschlechtert hat. Es ist noch zu erwähnen, dass das Spiel nicht extra für diese Bachelorarbeit erschaffen wurde, sondern unabhängig davon. Die theoretischen Grundlagen zu dieser Arbeit basieren im Wesentlichen auf dem ausführlichen Buch Artificial Intelligence For Games [2]. Alternativ könnte man noch das prägnantere Buch Artificial Intelligence for Computer Games [1] zurate ziehen. 1 Inhaltsverzeichnis 1 Einleitung 1.1 Künstliche Intelligenz oder Intelligente Agenten? . . . . 1.2 Künstliche Intelligenz in Computerspielen . . . . . . . 1.3 Warum eine Künstliche Intelligenz in einem Jump N Computerspiel? . . . . . . . . . . . . . . . . . . . . . . 1.4 Webseite des Jump n Runs . . . . . . . . . . . . . . . . 1.5 Ausblick auf die folgenden Kapitel . . . . . . . . . . . . . . . . . . Run . . . . . . . . . 2 Theorieteil 2.1 Aufbau einer Künstlichen Intelligenz in Computerspielen 2.2 Movement und Physik in Computerspielen . . . . . . . . 2.2.1 Physik in Computerspielen . . . . . . . . . . . . . 2.2.2 Dimensionen in Computerspielen . . . . . . . . . 2.2.3 Beschleunigung in Computerspielen . . . . . . . . 2.2.4 Gravitation in Computerspielen . . . . . . . . . . 2.2.5 Kollision in Computerspielen . . . . . . . . . . . . 2.3 Pathfinding in Computerspielen . . . . . . . . . . . . . . 2.3.1 Einleitung . . . . . . . . . . . . . . . . . . . . . . 2.3.2 1. Schritt: Graphenerstellung . . . . . . . . . . . . 2.3.3 2. Schritt: Shortest Path Algorithmus . . . . . . . 2.3.4 3. Schritt: Umformung der Lösung in Befehle . . . 2.3.5 4. Schritt: Ausführen von Befehlen . . . . . . . . 2.4 Decision Making in Computerspielen . . . . . . . . . . . 2.4.1 Einleitung . . . . . . . . . . . . . . . . . . . . . . 2.4.2 Decision Trees . . . . . . . . . . . . . . . . . . . . 2.4.3 State Machines . . . . . . . . . . . . . . . . . . . 2.4.4 Behavior Trees . . . . . . . . . . . . . . . . . . . 2.4.5 Fuzzy Logic, Markov Systems . . . . . . . . . . . 2.4.6 Goal-Oriented Behavior . . . . . . . . . . . . . . 2.4.7 Scripting . . . . . . . . . . . . . . . . . . . . . . . 2.4.8 Rule-Based Systems . . . . . . . . . . . . . . . . 2.4.9 Blackboard Architectures . . . . . . . . . . . . . . 3 Eigenes Konzept 3.1 Jump n Run mit zufälligen Levels . . . . . . . 3.2 Automatische Graphenerstellung . . . . . . . . 3.2.1 1. Ansatz: Erreichbarkeit von Objekten 3.2.2 2. Ansatz: Rasterung des Levels . . . . 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5 5 . . . 6 6 6 . . . . . . . . . . . . . . . . . . . . . . . 7 7 8 8 9 11 12 12 13 13 13 15 16 16 16 17 18 18 18 19 19 20 21 26 . . . . 27 27 28 29 30 3.2.3 3.3 3.4 3.5 3.6 3. Ansatz: Dynamische automatische Graphenerstellung und dynamisches Pathfinding . . . . . . . . . . Pathfinding . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 Dijkstra beim 1. Ansatz (Objekterreichbarkeit) . . . . 3.3.2 Gesteuerte Tiefensuche mit A* beim 2. Ansatz (Rasterung) . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.3 Abgeänderter A* beim 3. Ansatz (dynamische Graphenerstellung) . . . . . . . . . . . . . . . . . . . . . World Interfacing/Perception . . . . . . . . . . . . . . . . . Decision Making . . . . . . . . . . . . . . . . . . . . . . . . Regelerstellung . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.1 Grundregeln für ein 2d Sidescroller Jump n Run Computerspiel . . . . . . . . . . . . . . . . . . . . . . . . 3.6.2 Fortgeschrittenere Regeln für ein 2d Sidescroller Jump n Run Computerspiel . . . . . . . . . . . . . . . . . . 3.6.3 Allgemeine Anmerkungen zu den Regeln . . . . . . . Action Performer . . . . . . . . . . . . . . . . . . . . . . . . Perform-Way-Thread . . . . . . . . . . . . . . . . . . . . . . . 31 . 32 . 32 . 33 . . . . 34 35 35 35 . 36 . . . . 42 46 47 47 4 Evaluation 4.1 Bewertung der praktischen Umsetzung . . . . . . . . . . . . . 4.2 Anwendbarkeit der beschriebenen Elemente . . . . . . . . . . 4.2.1 Regelbasiertes System . . . . . . . . . . . . . . . . . . 4.2.2 Dynamic Rule Arbitration . . . . . . . . . . . . . . . . 4.2.3 Pathfinding . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Typisch auftretende Probleme . . . . . . . . . . . . . . . . . . 4.3.1 Pathfinding ergibt unmögliche Wege . . . . . . . . . . 4.3.2 Pathfinding erkennt gute Wege nicht . . . . . . . . . . 4.3.3 Der Agent kommt bei der Ausführung vom Weg ab . . 4.3.4 Pathfinding dauert zu lange . . . . . . . . . . . . . . . 4.3.5 Pathfinding sprengt den Speicher . . . . . . . . . . . . 4.3.6 Das Ausführen einer Regel schlägt fehl . . . . . . . . . 4.3.7 Endlosschleifen . . . . . . . . . . . . . . . . . . . . . . 4.3.8 Regeln behindern sich gegenseitig . . . . . . . . . . . . 4.3.9 Der Charakter läuft durch Objekte/Kollisionsprobleme 4.3.10 Der Charakter „betrügt“ . . . . . . . . . . . . . . . . . 4.3.11 Der Charakter sitzt fest . . . . . . . . . . . . . . . . . 4.3.12 Ist ein Objekt im Weg / Erreichbarkeit von Objekten . 4.3.13 Der Charakter könnte besser handeln . . . . . . . . . . 4.3.14 Das Hinzufügen der Regel ergibt schlechtere Ergebnisse 48 48 49 49 49 49 50 50 50 51 51 52 52 52 53 54 54 54 55 55 56 3.7 3.8 3 5 Resumé 56 5.1 Erreicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 5.2 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Literatur 57 4 1 1.1 Einleitung Künstliche Intelligenz oder Intelligente Agenten? „Künstliche Intelligenz“ ist in der Computerspieleindustrie noch der allgemein verwendete Begriff, auch wenn es sich eigentlich um „Intelligente Agenten“ handelt. Der Begriff Künstliche Intelligenz hat eine negative Konnotation, seitdem viele leere Versprechungen von den großen Urvätern der Künstlichen Intelligenz gegeben wurden (zum Beispiel [12]). Hier wird Künstliche Intelligenz als die Realisierung eines autonomen Agenten verstanden, der in der Lage ist, ein Jump N Run Computerspiel ähnlich wie ein menschlicher Spieler zu spielen. 1.2 Künstliche Intelligenz in Computerspielen In Computerspielen wurde Künstliche Intelligenz eigentlich nie als Simulieren der Gesamtheit eines Menschen (Strong AI, siehe [9]) aufgefasst. Traditionell wurde die Künstliche Intelligenz einfach nur als eine Möglichkeit gesehen, mehr Spaß in ein Spiel einzuführen. So ist es oft auch sinnlos, einen Computer perfekt spielen zu lassen, da das oft den kompletten Spielspaß zerstört. Auf der anderen Seite empfinden es Spieler als problematisch, wenn ein Computer etwas extrem „Dummes“ tut. Damit ist zum Beispiel das endlose Laufen gegen dieselbe Wand gemeint. Brian Reynolds sagte zu diesem Thema: „Beginnen Sie mit einer simplen Routine, die [...] Einheiten über die Karte wandern lässt [...]. Dann spielen Sie das Spiel [...] und beobachten Sie die Spielzüge des Computers. Verfolgen Sie das Treiben auf dem Monitor so lange, bis der Computer etwas wirklich Dummes macht [...]. Nun denken Sie darüber nach, was a) den Computer dazu veranlasst haben könnte, so etwas Dummes zu tun, b) was Sie anstelle des Computers getan hätten und c) welche Informationen ihrer Entscheidung zugrunde lagen. Anschließend arbeiten Sie die gewonnenen Informationen in ihren Algorithmus ein.“ ([3], S.219f). Dies beschreibt vor allem den Anfang der Künstlichen Intelligenz in Computerspielen. Es wurde sozusagen einfach drauflos programmiert und dann wurde der „Computer“ (oft benutzter Begriff in Computerspielen für eine Künstliche Intelligenz) beobachtet. Wenn der Computer etwas „Dummes“ tut, wurde der Algorithmus abwechselnd angepasst und getestet, bis der Computer nichts „Dummes“ mehr macht. Hierbei entsteht natürlich oft sinnloser Code, der schwer noch weiter zu editieren ist. Heutzutage macht man sich vorher Gedanken, wie man die Programmierung der Künstlichen Intelligenz besser strukturiert. 5 1.3 Warum eine Künstliche Intelligenz in einem Jump N Run Computerspiel? Es gibt wenige Versuche einen intelligenten Agenten, beziehungsweise eine Künstliche Intelligenz in einem Jump N Run Computerspiel spielen zu lassen. Aber vor allem das zufällige Kreieren der Levels erschwert die Erstellung der Künstlichen Intelligenz. Somit ist nämlich eine manuelle Vorverarbeitung des Levels unmöglich. Doch was ist der Zweck einer Künstlichen Intelligenz, die das Spiel selbst spielt? Nun, obwohl ihm die typische Rolle eines Spielers in einem Jump N Run Computerspiel genommen wurde, gäbe es verschiedene Möglichkeiten, das Spiel trotzdem für den Spieler interessant zu machen: • Man selbst baut Blöcke, um das Level zu verändern, während es gespielt wird. • Man hat diverse Möglichkeiten, den Agenten aufzuhalten. • Man hat diverse Möglichkeiten, dem Agenten zu helfen. • Es gibt ein Wettrennen. • Man fungiert als Manager in einem Wirtschaftsspiel. • Künstliche Intelligenz übernimmt das Spielen nur in gewissen Situationen. • Zeigen, wie das Level funktioniert. Das sind nur einige Ideen, wie man eine Künstliche Intelligenz sinnvoll in so eine Art von Spiel einbauen könnte. Wie sich dieses Spiel genau weiterentwickeln wird, steht zum Zeitpunkt der Niederschrift noch nicht fest. 1.4 Webseite des Jump n Runs Auf http://www.lernenspielen.com/ ist die aktuellste Version des Jump n Run Computerspiels verfügbar. Es ist ein Java Applet. Die Steuerung ist dort erklärt. Vieles, was in dieser Bachelorarbeit beschrieben wird, bezieht sich auf dieses Spiel. 1.5 Ausblick auf die folgenden Kapitel In Kapitel 2 ab Seite 7 geht es um grundsätzliche Dinge für Künstliche Intelligenz in Computerspielen, die in der Literatur bereits ausführlich erklärt wurden. Folgende Bereiche werden dort abgedeckt: 6 • Der Aufbau einer Künstlichen Intelligenz • Movement, also die Möglichkeiten zur Bewegung • Physik, also die Regeln, die für die Bewegung gelten • Pathfinding, also das Finden von Wegen, beziehungsweise das Bewegen von einem Punkt zu einem anderen • Decision Making, also das Treffen von Entscheidungen, vor allem darüber wie gehandelt werden soll, beziehungsweise darüber welche Aktion ausgeführt werden soll Das Kapitel 3 ab Seite 27 ist der Kern dieser Arbeit. Es beschreibt ein eigenes Konzept der Entwicklung einer Künstlichen Intelligenz für ein Jump N Run Computerspiel. Dabei geht es vor allem um folgendes: • Das Erstellen zufälliger Levels und die damit nötige automatische Graphenerstellung wird in 3 Pathfindingansätzen beschrieben. • Es wird kurz darauf eingegangen wie im eigenen Konzept das World Interfacing (Erhalten der Informationen) und das Decision Making (Entscheidungen treffen) implementiert wurden. • Die erstellten Regeln werden erklärt und es werden Tipps zur Regelerstellung gegeben. • Es wird auf das Ausführen der Aktionen und der gefundenen Wege eingegangen. Kapitel 4 beschreibt ab Seite 48 die Bewertung der praktischen Umsetzung, Anwendbarkeit der beschriebenen Elemente und dann werden noch viele typisch auftretende Probleme und deren Lösungen beschrieben. Dieses Kapitel kann als Nachschlagewerk bei Problemen dienen. Im letzten Kapitel 5 ab Seite 56 wird kurz beschrieben, was erreicht wurde und was noch zu erreichen ist. 2 2.1 Theorieteil Aufbau einer Künstlichen Intelligenz in Computerspielen In der Abbildung 1 kann man den typischen Aufbau einer Künstlichen Intelligenz sehen. Das World Interface übergibt Informationen und somit Wissen 7 an die Künstliche Intelligenz. Das Execution Management kontrolliert die Genauigkeit und die Reihenfolge der Ausführung. Die Group-AI (Künstliche Intelligenz für Gruppen) enthält die Strategy und beinhaltet die wichtigen Informationen zur Koordination mehrerer unabhängiger Charaktere mit Künstlicher Intelligenz. Die Character AI besteht aus Decision Making und Movement. Also was für Aktionen werden gewählt, wie werden sie gewählt und aus welchem Grund und weiteres. Die Entscheidungen der Künstlichen Intelligenz werden animiert und haben physikalische Folgen innerhalb des Spiels. Die Künstliche Intelligenz hat auch einen Einfluss in Content Creation, das heißt zum Beispiel, dass immer schwerere und komplexere Gegner eingeführt werden, die Künstliche Intelligenz beinhalten, vor allem in „MMORPGs“ (Massively Multiplayer Online Role-Playing Games) wie World of Warcraft von Blizzard Entertainment/Blizzard Activision, 2004. Die Künstliche Intelligenz hat auch einen Einfluss auf das Scripting, da man dort meist eine Künstliche Intelligenz in irgendeiner Form nachbaut, aber auch Techniken aus der Künstlichen Intelligenz benutzen kann. Weiterführendes gibt es in [2], auf den Seiten 3-35. 2.2 Movement und Physik in Computerspielen Um eine Künstliche Intelligenz in einem Computerspiel erstellen zu können, muss man sich zunächst einmal klar machen, was für Möglichkeiten der Agent, der gesteuert wird, denn besitzen soll. Ein wichtiger Aspekt, den man beachten muss, ist wie viel die Physik und das Movement (Bewegung) hierbei eine Rolle spielen, da diese meist den größten Unterschied zwischen verschiedenen Spielen darstellen. All die Unterschiede in diesen Spielen haben extreme Auswirkungen auf die Möglichkeiten des Agenten und somit auch direkt auf die Künstliche Intelligenz. Hier gibt es zum Beispiel den Unterschied, ob man in der Luft noch den Kurs des Fluges ändern kann, oder ist dieser unveränderbar? Man kann sich zum Beispiel vorstellen, wenn die Flugbahn noch veränderbar ist, muss man weniger im Voraus planen, als wenn dies nicht der Fall ist. 2.2.1 Physik in Computerspielen Wenn man eine Künstliche Intelligenz für ein Computerspiel entwickeln will, sollte man sich im Klaren sein, wie die Physik in dem Computerspiel eingehalten wird. Anhaltspunkte hierfür wären Kräfte, Gravitation, Impulse, Gesetz der Trägheit, Impulserhaltungssatz, Energieerhaltungssatz, Kollision, und Weitere. Meist werden Aspekte der Physik nicht, oder nur vereinfacht, modelliert. 8 Abbildung 1: Aufbau einer Künstlichen Intelligenz in Computerspielen. ([2], S.9) 2.2.2 Dimensionen in Computerspielen Zunächst sollte man sich folgende Fragen stellen: • In wie viele Dimensionen kann sich der Agent denn bewegen? • Sind diese unterschiedlich oder gleich? • Gibt es überhaupt so etwas wie Dimensionen zur Bewegung? In Abbildung 2 sieht man ein paar verschiedene Ansätze hierzu in Computerspielen. In dem etwas älteren Computerspiel Pong (Abbildung 2 oben links) ist es zum Beispiel nur möglich, sich auf dem Bildschirm nach oben und unten zu bewegen. Der Ball wiederum bewegt sich auch nach links und rechts. Es gibt aber keine Schwerkraft. 9 Abbildung 2: Dimensionen in Computerspielen. Das Bild beinhaltet die Spiele/Bilder: - Pong von Atari, 1972 (oben links) - Bomberman von Hudsonsoft/Ubisoft, 1983 (oben Mitte) - Super Mario Land von Nintendo, 1989 (oben rechts) - Unreal Tournament 3 von Epic Games, 2007 (unten links) - Flugsimulator [5] (unten Mitte) - Frei Fliegen [4] (unten rechts) In den Anfängen der Spielserie Bomberman von Hudson Soft (Abbildung 2 oben Mitte) blickt man von oben auf das Spiel und kann sich horizontal und vertikal auf dem Bildschirm bewegen, somit sind die zwei Dimensionen sehr ähnlich, da Schwerkraft keine Rolle spielt. Diese Art von Sicht nennt man Topdown. In den Anfängen der Super Mario Serie von Nintendo (Abbildung 2 oben rechts), was am ehesten dem Spiel entspricht, welches hier später vorgestellt wird, konnte man sich nach rechts und links frei bewegen, oder nach oben springen. Diese Ansicht nennt man Sidescroller und das Genre heißt Jump N Run (teilweise auch Platformer). Man wusste immer, dass sich das Ziel rechts befindet. In diesem Spielgenre gab es zum ersten Mal Schwerkraft und das war der Grund, dass sich die Dimensionen nicht mehr ähneln. Meist wurde die Schwerkraft aber nicht realistisch dargestellt, sondern man konnte linear, eine Weile nach oben springen und fiel dann wieder linear bis man landete. Man konnte sich jedoch auch in der Luft nach rechts und links bewegen, wie 10 auf dem Boden auch. Des Weiteren gibt es heutzutage schon dreidimensionale Computerspiele (Abbildung 2 unten links), in denen realistische Physik immer eine wichtige Rolle spielt. Ein wichtiges Genre ist hier der 3d Ego Shooter, in dem man sich am Boden in jede Richtung bewegen kann, wie in einem Topdown Spiel, aber gleichzeitig hat man die Möglichkeit, wie in einem Sidescroller zu springen. Somit hat man zwei Dimensionen, die sich funktional gleichen und eine Dimension, die sich von den anderen beiden Dimensionen funktional unterscheidet. Es wäre auch noch vorstellbar, dass man sich in drei Dimensionen bewegen kann, die sich von den Eigenschaften her völlig gleichen, ähnlich wie in einem Flugsimulator (Abbildung 2 unten rechts). 2.2.3 Beschleunigung in Computerspielen Abbildung 3: Dimensionen in Computerspielen. Des Weiteren sollte man sich darüber Gedanken machen, ob Beschleunigung eine Rolle spielt. Wirkt sich die Beschleunigung langsam auf die Geschwindigkeit aus und verändert diese (Abbildung 3 links) oder gibt es verschiedene Geschwindigkeiten zwischen denen man beliebig wechseln kann (Abbildung 3 rechts). In dem Computerspiel, das hier vorgestellt wird, ist das Zweite der Fall. Ansonsten müsste man das sogenannte „Steering Behavoir“ mit be11 trachten, also die Auswirkungen der Beschleunigung auf die Bewegung und das Planen. 2.2.4 Gravitation in Computerspielen Ein weiterer Aspekt ist die Schwerkraft beziehungsweise Gravitation. Gibt es Schwerkraft? Verändert die Schwerkraft langsam die Geschwindigkeit (Abbildung 4 links) oder gibt es nur diskrete Werte? (Abbildung 4 rechts) In Jump N Runs, wie später hier beschrieben, gibt es meist nur diskrete Werte. Abbildung 4: Gravitation in Computerspielen. Dieses Bild beinhaltet die Spiele/Bilder: - [7] (links) - Super Mario Land von Nintendo, 1989 (rechts) 2.2.5 Kollision in Computerspielen Wichtig ist zudem auch die Kollision. • Prallt man realistisch ab, im Sinne Einfallswinkel gleich Ausfallswinkel? (Abbildung 5 links) • Gibt es überhaupt kein Abprallen? (Abbildung 5 Mitte) • Gibt es einfach nur keinen Durchlass? (Abbildung 5 rechts) Das Letztere ist in dem Spiel, welches später vorgestellt wird, der Fall. 12 Abbildung 5: Kollisionen in Computerspielen. 2.3 2.3.1 Pathfinding in Computerspielen Einleitung In vielen Computerspielen ist das Pathfinding Teil des Spiels selbst. So ist es zum Beispiel in dem Echtzeitstrategiespiel Starcraft 2 von Blizzard Activision. Hier befiehlt man einer Einheit, sich zu einen bestimmten Punkt zu bewegen (Abbildung 6 links) und dann wird der kürzeste mögliche Weg berechnet und ausgeführt (Abbildung 6 rechts). Bei diesen Spielen ist es aber oft so, dass der Algorithmus mehr Informationen benutzt, als der Spieler haben sollte, was bei den Ansätzen, die hier erklärt werden, nicht der Fall ist. Für weitere Informationen kann in [2], auf den Seiten S.197-291 nachgeschlagen werden. Das Pathfinding verläuft normalerweise in mehreren Schritten, die nun vorgestellt werden. 2.3.2 1. Schritt: Graphenerstellung Das Spielfeld wird in einen Graphen überführt (Abbildung 7 rechts). Hierfür gibt es extrem viele Möglichkeiten, die je nach Genre passender oder unpassender sind. Hierbei wird die automatische Graphenerstellung und die manuelle Graphenerstellung unterschieden. Die manuelle Graphenerstellung hat den Vorteil, 13 Abbildung 6: Pathfinding in Computerspielen. Das Bild zeigt das Spiel StarCraft II: Wings of Liberty von Blizzard Entertainment/Blizzard Activision, 2010. dass man der Künstlichen Intelligenz sehr genaue Vorgaben geben kann und somit mehr Kontrolle darüber hat, welche Wege gegangen werden sollten. Außerdem ist dieser erstellte Graph dann meistens auf Speicher und Zeitverbrauch optimiert. Der Nachteil ist, dass für jedes Level erst manuell ein Graph erstellt werden muss und wenn das nicht passiert, ist die Künstliche Intelligenz überhaupt nicht mehr brauchbar. Weitere Nachteile werden bei [8] beschrieben und sie werden dort auch in einem Video demonstriert. In manchen Spielen ist es auch klar, was Spielfelder sind, wie zum Beispiel in Brettspielen. Hierbei sind die Spielfelder die Knoten und die Möglichkeiten, sich zwischen diesen Spielfeldern zu bewegen, die Verbindungen der Knoten. Das kann dann natürlich auch je nach Situation beziehungsweise Figur variieren, wie zum Beispiel beim Schach, bei dem jede Art von Figur andere Möglichkeiten hat, sich zu bewegen. In der automatischen Graphenerstellung gibt es zum Beispiel die Möglichkeit, jedes Pixel, beziehungsweise jede Kombination von x,y und z Werten des Spielfeldes (je nach Dimensionen), als einen Knoten anzusehen. Jede Möglichkeit, von einem Pixel zu einem anderen zu kommen, wird als eine Verbindung zwischen diesen Knoten definiert. Jedoch gibt es hier den Nachteil, dass es in den meisten Spielen entweder zu genau und somit ineffizient ist, teilweise auch gar keinen Sinn macht und oft sehr viel Arbeitsspeicher verbraucht. Manchmal kann es natürlich auch sinnvoll sein, wenn zum Beispiel das Spielfeld sehr klein ist. Die nächste Möglichkeit, die eng damit zusammenhängt, ist die Rasterung des Spielfeldes, so dass zum Beispiel 10x, 10y, 10z Werte eine Rasterung ausmachen. Hierbei senkt man bei einem dreidimensionalen Spiel immer14 hin die Komplexität auf 0,1%! Der Nachteil ist, dass es keine Möglichkeit mehr gibt, sehr genau zu arbeiten, denn durch diese Ungenauigkeit können verschiedene Fälle nicht mehr unterschieden werden. Hierbei könnten gute Möglichkeiten übersehen werden oder sogar Fehler entstehen. Die Grobheit der Rasterung ist proportional zur Schnelligkeit und zum Speicherverbrauch des Pathfindings, aber erhöht auch die Ungenauigkeit. Außerdem muss man dem Agenten erst beibringen, was unmöglich ist und was nicht. In Kapitel 3 wird ein eigenes Konzept hierzu vorgestellt. Eine weitere Möglichkeit, der automatischen Graphenerstellung, besteht darin, alle Objekte in der Welt als Knoten und alle Möglichkeiten, von einem Objekt zum anderen zu kommen, als Verbindungen zwischen den Knoten anzusehen. Hierfür ist es oft nötig, geometrische Berechnungen einzubauen. Ein Ansatz hierzu wird in Kapitel 3 vorgestellt. Hierbei ist die durchgezogene Oberfläche jedes Objekts ein Knoten und die Möglichkeit, zwischen den Knoten zu springen, eine Verbindung (Abbildung 7 links). Abbildung 7: Graphenerstellung in Computerspielen. 2.3.3 2. Schritt: Shortest Path Algorithmus Wenn man nun einen Graphen hat, kann man einen Shortest Path Algorithmus anwenden. In Abbildung 8 ist der Dijkstra Algorithmus beschrieben. Andere Möglichkeiten wären der A*-Algorithmus, Tiefensuche und Breitensuche und einige mehr. Hierzu gibt es reichlich Literatur, da es eine Kernproblematik der Informatik darstellt, deswegen wird hier nicht weiter auf die Theorie dahinter eingegangen. In Kapitel 3 wird in dem eigenen Ansatz jedoch noch etwas zur Anwendung der Algorithmen beschrieben. 15 Abbildung 8: Shortest Path Algorithmus. [6] 2.3.4 3. Schritt: Umformung der Lösung in Befehle Wenn man nun einen Weg hat, mit dem man ans Ziel kommt, muss man diesen Weg analysieren und in Befehle umformen (siehe Abbildung 9). 2.3.5 4. Schritt: Ausführen von Befehlen Wenn man den Lösungsweg in Befehle umgeformt hat, können diese nun ausgeführt werden (siehe Abbildung 10). Hierbei muss folgendes beachtet werden: • Was passiert, wenn man außerplanmäßig vom Weg abkommt? • Was passiert, wenn sich etwas außerplanmäßig im Weg verändert? 2.4 Decision Making in Computerspielen Decision Making beschreibt die Art, wie Entscheidungen getroffen werden. Hierbei gibt es verschiedene Modelle, die in [2], auf den Seiten 293-491, beschrieben werden. Es folgt nun eine kurze Einführung in die verschiedenen Arten von Modellen. 16 Abbildung 9: Lösung in Befehle Umformen in Computerspielen 2.4.1 Einleitung Es gibt unterschiedliche Ansätze des Decision Makings. Ein wichtiges Unterscheidungsmerkmal ist das Wissen des Agenten. Hierbei lassen sich folgende Möglichkeiten unterscheiden: • Er ist allwissend. • Er weiß, was er sieht. • Er weiß, was er gesehen hat. • Auf Grund von Gesehenem, schliesst er auf etwas anderes. Außerdem lässt sich noch unterscheiden, ob geplant wird oder nur reagiert. Des Weiteren könnte der Agent lernen. Zusätzlich sollte man wissen, ob die Künstliche Intelligenz einen Spieler simulieren soll. Hat sie dieselben Möglichkeiten, zu agieren, die auch ein Spieler hat oder besitzt sie eventuell andere Möglichkeiten, Entscheidungen zu treffen. Um eine Entscheidung zu treffen, braucht man erst eine Auswahl an möglichen Entscheidungen. Die Aktion, die durch eine Entscheidung hervorgerufen wird, kann einfach sein, etwa das Drücken oder Loslassen einer Taste, ähnlich wie beim Spieler, aber auch komplexere Aktionen, wie das Ausführen eines gefundenen Weges durch Pathfinding. Weiterführendes kann in [2], auf Seite 293-491 nachgelesen werden. 17 Abbildung 10: Befehle Ausführen in Computerspielen 2.4.2 Decision Trees Bei Decision Trees handelt es sich um Entscheidungsbäume (siehe Abbildung 11). Man stellt sich verschiedene Fragen und je nach Antwort, handelt man. Dies ist zu vergleichen mit einer „if-then-else“-Verschachtelung. ([2], S.293308) 2.4.3 State Machines Eine State Machine (siehe Abbildung 12) ist so aufgebaut, dass man sich in Zuständen befindet und die Zustände durch Events gewechselt werden. Je nach Zustand wird dann gehandelt. ([2], S.309-333) 2.4.4 Behavior Trees Behavior Trees (siehe Abbildung 13) sind ähnlich wie Decision Trees, eine Möglichkeit, eine „if-then-else“-Verschachtelung visuell darzustellen. Der Unterschied zu einem Decision Tree ist nur, dass es sich hierbei um eine Abfolge von Aktionen handelt. ([2], S.334-370) 18 Abbildung 11: Decision Tree. ([2], S. 297) 2.4.5 Fuzzy Logic, Markov Systems Bei den Markov Systems handelt es sich um eine Erweiterung der Fuzzy Logic (siehe Abbildung 14). Wenn bei der Entwicklung der Künstlichen Intelligenz die Notwendigkeit besteht, Aktionen nicht nur richtig oder falsch zu sehen, sondern ihnen auch Kommazahlen zuzuweisen, sollte man die Seiten 371-400 in [2] lesen. 2.4.6 Goal-Oriented Behavior Goal-Oriented Behavior, also sozusagen das zielorientierte Handeln, sieht eigentlich so aus, dass man sich verschiedene Ziele setzt und dann versucht, diese zu erreichen. Diese Art des Decision Makings wird nur sehr selten in Computerspielen eingesetzt. Die Ziele eines Agenten sind meistens sehr komplex und sie sind von vornherein klar, so dass sich diese Methode in vielen Fällen einfach nicht lohnt. Man könnte es allerdings auch so sehen, dass jede Art von Künstlicher Intelligenz implizit zu dieser Kategorie gehört, nur dass die Ziele sozusagen fest einprogrammiert sind. ([2], S.401-426) 19 Abbildung 12: State Machine. ([2], S. 310) 2.4.7 Scripting Beim Scripting handelt es sich darum, dass man die Entscheidungen der Künstlichen Intelligenz im Vornherein trifft und den computergesteuerten Objekten ganz genau sagt, was zu tun ist. Hier kann man gleich mehrere Bedeutungen des Wortes Script anwenden. Einerseits verhält man sich wie ein Regisseur und gibt dem Agenten genaue Anweisungen, wo er was zu tun hat. Andererseits kann man auch das aus der Programmierung stammende „Script schreiben“ als Bedeutung verwenden. Meistens handelt es sich hierbei um Erweiterungen eines Spieles, die nicht von den Entwicklern des Spiel selbst geschrieben wurden, oder zumindest auch von einer anderen Person geschrieben sein könnten. Ein gutes Beispiel hierfür ist das Entwickeln eigener „Custom Maps“ in den Blizzard Spielen „Warcraft 3“ und „Starcraft 2“, bei denen sogar neue Genres entstanden sind. Die wichtigsten dieser neuen Genres sind Tower Defence und Dota (Defence of the Ancients). Bei der Entwicklung eines Tower Defence (siehe Abbildung 15) wurde das Grundspiel nur leicht verändert, um ein völlig neues Genre zu erschaffen. Es wurden alle anderen Gebäude entfernt, so dass ein Spieler nur Tower bauen kann. Auch wurde die Vielfältigkeit und 20 Abbildung 13: Behavior Tree. ([2], S. 339) Variation der Tower erhöht. Außerdem werden Gegner an einem Startpunkt erstellt und laufen einen bestimmten Weg. Diese Gegner sollen aufgehalten werden, wenn sie aber das Ziel erreichen, verliert der Spieler ein Leben. Das Ziel des Spiels ist es lange zu überleben und man verliert, sobald die Leben 0 erreichen. Eigentlich handelt es bei Starcraft 2 um ein Echtzeitstrategiespiel. Doch wenn man diese Karte auswählt, fühlt es sich so an, als würde man ein ganz anderes Genre spielen, auch wenn nur wenige Eigenschaften durch Scripts verändert wurden. ([2], S.466-479) 2.4.8 Rule-Based Systems Ein Rule-Based System (siehe Abbildung 16), also regelbasiertes System besteht aus Rules, einem Arbiter und einer Database. Bei den Rules handelt es sich um die Entscheidungsmöglichkeiten, die der Agent hat. Der Arbiter ist die entscheidende Instanz. Die Database enthält das Wissen, das der Arbiter 21 Abbildung 14: Fuzzy Logic, Markov Systems. ([2], S. 375) benötigt, um die Entscheidungen zu treffen. ([2], S.427-459) 2.4.8.1 Database Die Datenbank enthält das Wissen des Agenten. Hierbei handelt es sich nicht immer um vollständiges Wissen, sondern um das Wissen, das der Agent durch World Interfacing (siehe 3.4 auf Seite 35) von der Spielwelt erhält. Die Datenbank kann logische boolean Werte, aber auch andere Datentypen, enthalten. ([2], S.427-459) 2.4.8.2 Rules Regeln bestehen aus einer Vorbedingung (Precondition), einer Aktion (Action) und aus einer optionalen Priorität (Priority). Wenn die Vorbedingung erfüllt ist, wird eine Liste von Bindings zurückgegeben. Diese können vier Arten von Bindings enthalten: • false (Die Regel ist nicht anwendbar.) • true (Die Regel ist anwendbar.) • Die verschiedenen Wege, die ausgeführt werden können • Sonstige Unterscheidungsmerkmale, die man braucht, um eine Regel mehrfach anzuwenden 22 Abbildung 15: Scripting. Die Bilder stammen aus dem Starcraft 2 Map Editor von Blizzard Entertainment/Blizzard Activision, 2010. Links sieht man, wie auf einer Map Regionen und Punkte definiert werden. Rechts sieht man den Editor zum Schreiben eines Scripts. Beide Ansichten sind Teile des Starcraft 2 Map Editors. Nun sucht der Arbiter, nach verschiedenen Kriterien, eine Regel mit zugehörigem Binding aus und schickt die Aktion an den Action Performer. Dieser meldet zurück, wenn die Aktion erfolgreich zu Ende gebracht wurde, oder an was die Aktion gescheitert ist. Nun werden wieder alle Regeln nach Vorbedingungen überprüft und es geht von vorne los. ([2], S.427-459) 2.4.8.2.1 Precondition Die Precondition muss erfüllt sein, damit die Aktion ausgeführt werden kann. Es kann einfache Preconditons geben, die immer wahr sind, wenn zum Beispiel eine Leerlaufaktion mit niedriger Priorität erkennen soll, dass nichts zu tun ist. Es kann aber auch zum Beispiel die Database gefragt werden, ob ein gewisser Wert erreicht wurde. Zum Beispiel könnte man einer Regel, bei der es darum geht, sich Heilung zu besorgen, eine Precondition einbauen, dass die Leben niedrig sind. Außerdem könnte man verschiedene Bindings an den Arbiter liefern, wenn die Regel zum Beispiel heißen würde „Sammel ein Blatt auf “. Dann würde in der Precondition erst überprüft werden, was für Blätter in der Nähe sind. Als nächstes würden Wege mit dem Pathfinding gefunden werden und diese Wege würden dann als Bindings zurückgegeben werden. Doch wenn kein einziger Weg gefunden wird, sind die Preconditions nicht erfüllt. Wenn die Preconditions nicht erfüllt sind, wird diese Regel auch nicht beachtet. ([2], S.427-459) 23 Abbildung 16: Rule-Based Systems. ([2], S. 428) 2.4.8.2.2 Action Die Aktion mit zugehörigem Binding wird an den Action Performer gesendet, wenn die Precondition erfüllt wurde und der Arbiter diese Regel ausgewählt hat. Das Ausführen einer Aktion entspricht zum Beispiel dem Drücken oder Loslassen einer Taste auf dem Keyboard. Es wird natürlich nicht wirklich auf die Tastatur geklickt, sondern der KeyListener oder MouseListener empfängt ein dementsprechendes Event, das auch zum Beispiel beim Drücken einer Taste auf dem Keyboard entstehen würde. Dies ist natürlich nur sinnvoll, wenn der Anspruch ist, einen wirklichen Spieler nachzuahmen. Alternativ können auch direkt die Eigenschaften des Charakters verändert werden. Allerdings sollte man sich im Klaren sein, inwiefern der Agent dann die Möglichkeit besitzt, zu betrügen. Im weiteren Verlauf wird davon ausgegangen, dass das Senden von Keyboard- und MouseEvents als einzig richtige Lösung anzusehen ist. Aber eine Aktion muss nicht unbedingt aus dem Senden eines einzigen Events bestehen. Es gibt auch zum Beispiel die Möglichkeit, dass der Action Performer einen Weg bekommt, dieser wird an einen „Perform-Way-Thread“ weitergeleitet. Dieser „Perform-Way-Thread“ generiert, je nach momentaner Position und je nach Weg, immer wieder KeyboardEvents bis das Ende des Weges erreicht wurde, oder erkannt wird, dass der Weg nicht möglich ist. ([2], S.427-459) 2.4.8.2.3 Priority Die Priorität einer Aktion ist nur optional und je nach Rule Arbitration (siehe 2.4.8.3 auf Seite 25) vom jeweiligen Binding abhängig. Wenn das Binding 24 besagt, dass die Precondition nicht erfüllt ist, ist die Priorität am besten -1 oder ein anderer absurder Wert. Ansonsten sollte die Priorität der Wichtigkeit der Aktion entsprechen. ([2], S.427-459) 2.4.8.3 Rule Arbitration Bei der Rule Arbitration geht es darum, welche Kriterien sind entscheidend, um eine Regel auszuwählen. ([2], S.441-442) 2.4.8.3.1 First Applicable Die erste Regel, die die Vorbedingungen erfüllt, wird gewählt. Hier ist der Vorteil, dass man die Reihenfolge der Regeln vorher so setzen kann, dass die erste Aktion, die die Vorbedingungen erfüllt auch wirklich die Aktion ist, die dann ausgeführt werden sollte. Ein weiterer Vorteil ist, dass nicht alle Regeln erst auf Vorbedingungserfüllung überprüft werden müssen. ([2], S.441f) 2.4.8.3.2 Least Recently Used Die Regeln werden absteigend nach zeitlichem Abstand der letzten Benutzung geordnet und die erste Regel, die die Vorbedingung erfüllt, wird ausgewählt. Der Vorteil hierbei ist, dass verhindert wird, dass ein Agent immer dieselbe Regel benutzt. Der Nachteil ist, dass nicht beachtet wird, dass eine Regel eventuell kritischer oder wichtiger ist, als eine andere. ([2], S.442) 2.4.8.3.3 Random Rule Die Regeln werden zufällig geordnet und die erste Regel, die die Vorbedingung erfüllt, wird ausgewählt. Der Vorteil und Nachteil zugleich ist, dass es schwer vorhersehbar ist, was der Agent nun auswählen wird. Dies kann je nach Genre erwünschenswert sein oder auch nicht. Ein reiner Nachteil ist jedoch, dass nicht beachtet wird, dass eine Regel eventuell kritischer oder wichtiger ist, als eine andere. ([2], S.442) 2.4.8.3.4 Most Specific Conditions Eine Regel, die die meisten Einschränkungen in der Vorbedingung hat und alle Vorbedingungen erfüllt, wird gewählt. Hierbei handelt es sich eigentlich um ein vorher geordnetes First Applicable. ([2], S.442) 2.4.8.3.5 Dynamic Priority Arbitration Wenn man die feste Prioritäten für jede Aktion setzt, würde es sich auch um ein vorher geordnetes First Applicable handeln. Anders ist es jedoch, wenn man die Priorität der Aktion vom Binding und dem Wissen abhängig macht. Zum Beispiel ist es wichtiger, sich zu heilen, je weniger Leben man hat. Der 25 Vorteil ist also, dass sich die Priorität einer Aktion abhängig von den Umständen, dem Binding und eventuell auch dem Zufall stetig verändern kann. Da die Priorität vom Binding abhängt, ist es notwendig, erst die Preconditions aller Regeln zu überprüfen. Danach wird das Binding mit der höchsten Priorität gewählt und dessen Aktion an den Action Performer gesendet. Diese Art Regeln auszuwählen, verlangt es, alle Regeln durchzugehen und erfordert somit eine effiziente Überprüfung der Preconditions. ([2], S.442f) 2.4.9 Blackboard Architectures Eine Blackboard Architecture (siehe Abbildung 17) ist eine Ansammlung von mehreren Rule-Based Systems, die jeweils Experten für ein gewisses Fachgebiet darstellen. Ein Arbiter entscheidet, welcher „Experte“ das Sagen bekommt und lässt ihn so lange handeln, bis er die Kontrolle wieder freigibt. ([2], S.459-466) Abbildung 17: Blackboard Architecture. ([2], S. 460) 26 3 Eigenes Konzept Das ganze Kapitel bezieht sich auf das Jump N Run Computerspiel, dass auf http://www.lernenspielen.com/jumpnruntesten.html getestet werden kann. Angewandt wird die Künstliche Intelligenz auf ein Jump N Run Computerspiel mit zufällig erstellten Levels (siehe Kapitel 3.1 auf Seite 27). Um Pathfinding in zufälligen erstellten Levels zu ermöglichen, wurden verschiedene Konzepte entwickelt, um automatisch Graphen für das Pathfinding zu erstellen (siehe Kapitel 3.2 auf Seite 28). Beim eigenen Konzept handelt es sich um eine Künstliche Intelligenz als Rule-Based System (siehe Kapitel 2.4.8 auf Seite 21) mit „Dynamic Priority Arbitration“ (siehe Kapitel 2.4.8.3.5 auf Seite 25). Es wird auf das Erstellen von Regeln eingegangen und die erstellten Regeln werden vereinfacht aufgelistet und kommentiert (siehe Kapitel 3.6 auf Seite 35). Auch auf das Decision Making (Entscheidungen treffen), das World Interfacing (Wie erhält die Künstliche Intelligenz das Wissen?) und den Action Performer (Wie werden Aktionen ausgeführt?) wird kurz eingegangen. Des Weiteren wird die Anwendbarkeit diskutiert (siehe Kapitel 4.2 auf Seite 49) und es werden die typisch auftretenden Probleme mit Lösungsvorschlägen aufgezählt (siehe Kapitel 4.3 auf Seite 50). 3.1 Jump n Run mit zufälligen Levels Das Spiel (http://www.lernenspielen.com/jumpnruntesten.html), auf das das eigene Konzept angewandt wird, wurde unabhängig von der Bachelorarbeit in Java programmiert. Es geht darum, als eine Art Marienkäfer durch ein Level zu laufen, wobei dieses Level zufällig erstellt wurde. Es gibt feste Gegebenheiten für das Level: • Die erste Wolke, auf der man zu Beginn des Level steht • Eine Blockade, die verhindert, dass man nicht links aus dem Level gehen kann • Eine Art Lava, die sich circa 900 Pixel unter dem Startpunkt befindet und sich über das gesamte Level erstreckt (Bei Berührung stirbt der Charakter.) • Das Finish ist 20000 Pixel vom Startpunkt entfernt. • Man sieht 1000 mal 1000 Pixel. 27 • Wenn der Charakter stirbt, startet er auf derselben x-Koordinate, auf der Start-y-Koordinate und ist kurz unsterblich, hat aber ein Leben weniger. Falls der Charakter kein Leben mehr hat, ist das Spiel vorbei. Zufällig werden hinzugefügt: • Wolken, die nicht blockieren, aber den Charakter halten, sofern er sich darüber befindet • Holz, das blockiert und den Charakter hält, sofern er sich darüber befindet • Blätter, die man aufsammeln kann • 3 Äste, die man aufsammeln kann (Diese sind jedoch nur schwer zu erreichen.) • Feuer, das dem Charakter bei Auftreffen alle Blätter entzieht und sie in der Gegend verstreut (Falls der Charakter hierbei kein Blatt hat, „stirbt“ er, genau wie in der Lava.) In diesem Spiel sind Objekte im Level auf einen Bereich verteilt, der sich über 2000 Pixel hoch und 20000 und mehr Pixel zur Seite erstreckt. Die Levels werden mit steigendem Schwierigkeitsgrad immer länger. Zusätzlich gibt es mit zunehmenden Schwierigkeitsgrad weniger haltende Objekte und mehr Objekte, die Schaden zufügen. Wenn das Ziel in einem Level erreicht wurde, wird der Schwierigkeitsgrad erhöht und man wird in das nächste Level gesetzt. Es gibt theoretisch unendlich viele Level. Durch das zufällige Erstellen der Levels, kann ein Level mit höherem Schwierigkeitsgrad jedoch leichter zu schaffen sein, als ein anderes mit niedrigerem Schwierigkeitsgrad. 3.2 Automatische Graphenerstellung Für die Erstellung der meisten komplexen und planenden Regeln ist es notwendig zu wissen, ob es einen Weg von einem Punkt zu einem anderen Punkt gibt. Das Pathfinding (siehe Kapitel 2.3 auf Seite 13) liefert dieses Wissen und gibt sogar den Weg zurück, den man dann später zur Ausführung benötigt. Ein wichtiger Teil des Pathfindings ist die Überführung des Spieles in einen Graphen (siehe Kapitel 2.3.2 auf Seite 13). Dieser Graph kann normalerweise in der Leveldesignphase manuell definiert werden. Doch dadurch, dass die Levels erst bei Laufzeit entstehen, ist es notwendig, diesen Prozess zu automatisieren. Es gibt drei Ansätze für die automatische Graphenerstellung, die an diesem Spiel getestet wurden. 28 Im ersten Ansatz geht es darum, die Objekte als Knoten und die Erreichbarkeit zwischen den Knoten als Verbindungen zwischen den Knoten zu sehen. Diese Erreichbarkeit wird durch eine optimale Sprungfunktion überprüft. Es handelt sich hierbei um eine Art Ausschlussverfahren. Der zweite Ansatz enthält die Rasterung des Levels in jeweils 10 mal 10 Pixel. Als nächstes wird dann überprüft, wie viele Rasterungen das Objekt schneidet, um diese dann mit den Eigenschaften des Objektes zu versehen. Der dritte Ansatz erstellt erst beim Pathfinding selbst einen Graphen. So werden sowohl pixelgenaue Bewegungen, als auch große Bewegungsabläufe, wie ein kompletter Sprung oder langes Laufen in eine Richtung, in Betracht gezogen. 3.2.1 1. Ansatz: Erreichbarkeit von Objekten Objekte entsprechen den Kanten eines Graphen. Die Erreichbarkeit zwischen Objekten entspricht den Verbindungen zwischen Kanten. 3.2.1.1 Erstellung der Kanten Bei der Erstellung der Kanten/Knoten eines Graphens (siehe Abbildung 18), betrachtet man alle möglichen Oberflächen von Objekten, die nicht verdeckt werden, als eine Kante. Abbildung 18: Das Erstellen von Knoten 3.2.1.2 Optimale Sprungfunktion Die optimale Sprungfunktion dient dazu, festzustellen, ob ein Objekt durch Sprung erreichbar ist oder nicht (siehe Abbildung 19 und Abbildung 20). Wenn das Objekt sich in dem NICHT ERREICHBAR Bereich befindet, ist es auf jeden Fall nicht erreichbar und kann somit ausgeschlossen werden. Wenn es sich in dem VIELLEICHT ERREICHBAR Bereich befindet, ist es notwendig zu überprüfen, ob ein Objekt (schadend, haltend oder blockend) die optimale Sprungfunktion bis zu dem zu erreichenden Objekt schneidet. Dies gilt auch in dem Bereich zwischen der optimalen Sprungfunktion über 29 Abbildung 19: Optimale Sprungfunktion dem zu erreichbaren Objekt und dem zu erreichbaren Objekt selbst. Wenn sich ein Objekt im Weg befindet, muss die Funktion angepasst werden (siehe Abbildung 21). Wenn also nur ein oder kein Objekt im Weg war, kann man sicher sagen, dass das zu erreichende Objekt erreichbar ist und man weiß sogar wie. Doch wenn die abgeänderte Funktion nun wieder geschnitten wird, gibt es überabzählbar viele neue Möglichkeiten, wie die Funktion verändert werden könnte. Es wurden verschiedene Lösungsmöglichkeiten, für dieses Problem, getestet, doch keine war so richtig zufriedenstellend, da es bei jedem weiteren Objekt, das sich im Weg befindet, exponentiell mehr Wegmöglichkeiten wurden. Außerdem wurde das Springen von unten auf ein Objekt, das sich oben befindet, nicht einbezogen. Aus den oben genannten Gründen wurde nach einer neuen Möglichkeit des Pathfindings gesucht. 3.2.2 2. Ansatz: Rasterung des Levels Die Rasterung des Levels (siehe Abbildung 22) wird jedes mal, wenn ein neues Objekt entdeckt wird, aktualisiert. Außerdem wird lediglich für jeden Pixelblock (in diesem Fall 10x und 10y Pixel also 100 „xy-Paare“) gespeichert, ob sich dort ein haltendes, ein blockendes und ein schadendes Element, sowie ein Blatt oder ein Ast befindet. Doch da im Voraus festgelegt wird, dass immer 10 mal 10 Pixel betrachtet werden und nur gespeichert wird, ob sich dort überhaupt mindestens eine Ausführung von dem jeweiligen Objekttyp befindet, oder eben nicht, hat man manchmal Ungenauigkeiten, die man dann nur schwer wieder in den Griff bekommt. In manchen Fällen ist es zu ungenau, in anderen Fällen ist es dann wiederum zu genau. 30 Abbildung 20: Verlauf der optimalen Sprungfunktion Das positive an diesem Ansatz ist jedoch, dass er der erste funktionierende Pathfindingansatz war, der innerhalb der Künstlichen Intelligenz zu einigermaßen guten Ergebnissen führte. Allerdings hatte das statische Pixelrastern zwei Nachteile: Einerseits war diese Genauigkeit manchmal nicht nötig und somit leidet die Geschwindigkeit und der Speicherbedarf. Andererseits war es manchmal auch zu ungenau, so dass Fehler entstanden, die schwierig in den Griff zu bekommen sind. Zwar wurden die Fehler größtenteils beseitigt, aber dann kam die Frage auf, warum man eigentlich so an diesen 10 mal 10 Pixeln festhält. Besser wäre doch ein dynamisches System, das je nach Bedarf die Genauigkeit verändern kann. Somit könnte man Speicherbedarf, Zeitbedarf und Genauigkeit für jeden Abschnitt so optimieren, dass man viel bessere Ergebnisse erzielt. Die Lösung sollte die Entwicklung einer dynamischen automatischen Graphenerstellung sein. 3.2.3 3. Ansatz: Dynamische automatische Graphenerstellung und dynamisches Pathfinding Die dynamische automatische Graphenerstellung (siehe Abbildung 23) macht sich Bewegungsmuster zu nutze, die oft auftreten. So wird von jedem Punkt aus nicht nur der nächste Pixel oder Pixelblock überprüft, sondern es werden auch typische Bewegungsabläufe als mögliche nächste Aktion gesehen. Man erhält dabei eine viel größere Anzahl an möglichen nächsten Aktionen. Um es am Beispiel des „Nach Rechts Springens“ einmal anzudeuten, gibt es 31 Abbildung 21: Veränderung der optimalen Sprungfunktion viele mögliche Genauigkeiten einen Sprung zu überprüfen. So kann man zum Beispiel erst überprüfen, ob sich ein Objekt im Weg befindet, wenn man den kompletten Sprung durchführen will (nur den Weg nach oben, noch nicht das Fallen). Als nächstes verringert man die Länge des Sprunges bis kurz davor, und setzt das als einen neuen Knoten im Pathfinding fest. Außerdem werden auch 50% des Sprunges, 10% des Sprunges, 5% des Sprunges, und 1 Pixel des Sprunges als Knoten hinzugefügt. Dies erfolgt nach Überprüfung, ob der Weg möglich ist. Hierbei sollte auch überprüft werden, ob der Weg schon in der Liste an möglichen Wegen enthalten ist. Außerdem sollte man noch nach Zyklen prüfen. Um es noch weiter am Beispiel „nach rechts laufen“ auszuführen, kann man folgende Fälle unterscheiden: 1000, 400, 100, 50, 10, 5 oder 1 Pixel nach rechts laufen. Bei jeder Aktion wird an jedem Zwischenpunkt überprüft, ob sich etwas im Weg befindet oder die Aktion aus sonst einem Grund nicht mehr möglich ist. Das Ende der Aktion wird dann auf die mögliche Aktionslänge reduziert. Falls dadurch dann Knoten entstehen, die sich gleichen, wird natürlich nur einer davon genommen. Dieser Graph wird jedoch im Gegensatz zur Graphenerstellung durch Rasterung des Levels erst dynamisch zum Pathfinding erstellt, was die Dauer des Pathfindings je nach Implementation eventuell erhöhen kann. 3.3 3.3.1 Pathfinding Dijkstra beim 1. Ansatz (Objekterreichbarkeit) Es wird überprüft, auf welchem Objekt sich der Spieler befindet und der dazugehörige Knoten wird als Anfangsknoten gewählt. Nun wird der Dijkstra 32 Abbildung 22: Veranschaulichung der Rasterung eines Spielfeldes. Hier kann man zum Beispiel sehen, dass sich in B1 und C2 jeweils ein rotes und ein braunes Objekt befindet. Man kann jedoch nicht mehr rekonstruieren, ob sich das Objekt überhaupt erreichen lässt. Algorithmus angewandt. Bei jedem Schritt wird auch überprüft, ob man von dem momentanen Objekt direkt zum Ziel des Pathfindings springen kann. Wenn dies der Fall ist, wird der Weg gespeichert und zurückgegeben. Dieser Weg wird dem Arbiter dann als Binding übergeben. Der Dijkstra Algorithmus selbst wird hier als Wissen vorausgesetzt, da es sich um einen zentralen Aspekt der Informatik handelt. 3.3.2 Gesteuerte Tiefensuche mit A* beim 2. Ansatz (Rasterung) In „javaähnlicher“ Form auf den Punkt gebracht, wie es ungefähr aussehen sollte: 33 Abbildung 23: Veranschaulichung der Wegmöglichkeiten des dynamischen Pathfindings. pathfinder ( Ort ort , Ort to ){ if ( ort != to ){ try { A *( ort , to ); } catch ( St ac kO ve rF lo wE rr or e ){ } for ( each direction i ){ isPossible ( neuerOrtDurch ( i )){ pathfinder ( neuerOrtDurch ( i ) , to ); } } } } Die richtige Auswahl der Richtungen ist hier extrem wichtig. Der A* Algorithmus selbst wird wie der Dijkstra Algorithmus als Wissen vorausgesetzt. 3.3.3 Abgeänderter A* beim 3. Ansatz (dynamische Graphenerstellung) Erst erstellt man für einen Knoten alle Folgeknoten, wie in Kapitel 3.2.3 auf Seite 31 beschrieben. Nun könnte man den normalen A* Algorithmus verwenden und den nächsten besten Knoten mit einer unterschätzenden Heuristik und einer bisherigen Wegberechnung bestimmen. Doch in diesem Fall würde das zu einer Menge Overhead führen, denn eigentlich ist der Sinn, dass 34 die ungenauen Knoten viel priorisierter expandiert werden, als die genaueren Knoten. Also ist es notwendig, dass der bisherige Weg viel weniger gewichtet wird, als die Heuristik des noch ausstehenden Weges. Eine mögliche Ausführung wäre dies: P Bisheriger Weg: 2 · max (x,y) + 1 · min (x,y) + 1 T eilabschnitte Restheuristik: 10 · max(x,y) + 5 · min (x,y) Erklärung: x (y) ist der x- (y-) Abstand, der in den jeweiligen Teilabschnitten des bisherigen Weges zurückgelegt werden musste. Bei der Restheuristik ist x (y) der Abstand, zwischen der zu erwartenden Position und dem Ziel. Nun zählt man für jeden neuen Knoten den bisherigen Weg und die Restheuristik zusammen und fügt sie der Liste noch zu expandierender Knoten hinzu. Der Knoten der Liste mit dem niedrigsten Wert wird expandiert. Expandierte Knoten werden aus der Liste entfernt. 3.4 World Interfacing/Perception Das World Interfacing erfolgt dadurch, dass zu jedem Frame überprüft wird, welches Objekt vom Spieler zur Zeit gesehen wird. Diese werden an die Database der Künstlichen Intelligenz gesendet und dort, je nach Verwendungszweck, verarbeitet. 3.5 Decision Making Das Decision Making basiert auf dem, im Theorieteil erwähnten, Rule-Based System (siehe Kapitel 2.4.8 auf Seite 21) mit „Dynamic Priority Arbitration“ (siehe Kapitel 2.4.8.3.5 auf Seite 25). Die Priorität der Regeln hängt von verschiedenen Werten und auch vom Zufall ab. Doch wenn die Priorität gleich ist, wird zufällig eine Regel mit einem Binding ausgewählt. Auch das Konzept der Bindings wurde eingeführt, mit dem man mehrere Arten erlauben konnte, eine Regel auszuführen. So wird zum Beispiel bei „ein Blatt einsammeln“ in der Precondition jedes Blatt in der Nähe geordnet und dann nacheinander ein Weg dazu gesucht. Zusätzlich werden Objekte kurzzeitig deaktiviert, wenn das Pathfinding fehlschlägt. 3.6 Regelerstellung Zunächst wurden grundsätzliche Regeln erstellt, wie „Nach Rechts Laufen“, „Springen“ und „Rennen“. Erst dann wurde das System getestet. Falls sich 35 der Agent jedoch anders verhält, als er sollte, wird eine neue Regel hinzugefügt, die womöglich dieses Verhalten simulieren könnte. 3.6.1 Grundregeln für ein 2d Sidescroller Jump n Run Computerspiel In einem Jump n Run gibt es ein paar grundlegende Faustregeln, die fast immer gelten: • Rennen: Man sollte immer rennen, wenn dies möglich ist. • Nach rechts bewegen: Man sollte meistens nach rechts laufen, wenn dies sinnvoll ist. • Springen: Wenn rechts ein Abgrund oder ein Hindernis ist, ist es meistens sinnvoll zu springen. • Fallen lassen: Wenn man fällt oder fliegt und sich ein sicher zu erreichendes Objekt unter einem befindet, sollte man sich meistens fallen lassen. • Schadende Objekte meiden: Es ist meistens besser, schadende Objekte zu umgehen. Diese einfachen Regeln ergeben schon eine relativ umfassende Künstliche Intelligenz, die in sehr vielen Fällen zu guten Ergebnissen führt. Natürlich muss man noch bei jedem Spiel die Besonderheiten des Spiels oder des Levels mit beachten und eventuell weitere Regeln erstellen. Einige Regelansätze für typische Probleme werden im Folgenden etwas ausführlicher beschrieben. 3.6.1.1 Einfache Regeln (essentiell und effizient) Name: Rennen Precondition: Rennen ist nicht angeschaltet Action: Rennen anschalten Priority: 100 Bewertung und Kommentare zur Regel „Rennen“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. In diesem Spiel ist es eigentlich nie sinnvoll, nicht zu rennen. Der „Rennen-Modus“ wird also automatisch angeschaltet und bleibt für den 36 Rest des Spiels bestehen. Dies geschieht, indem ein „Shift-Button-PressedEvent“ an den KeyListener gesendet wird. Da es hier keine Beschränkung gibt, macht es auch keinen Sinn, zu sparen oder ähnliches. Das kann natürlich in einem anderen Spiel anders aussehen. Wenn es zum Beispiel Kosten für das Rennen gibt, ist es noch abzuwägen, ob dies in dieser Situation sinnvoll ist. Auch das Abschalten des Rennens müsste dann in Betracht gezogen werden. Name: Nach rechts laufen Precondition: • Rechts ist nichts im Weg, was blockiert und • rechts ist nichts Schadendes im Weg und • rechts ist kein Abgrund Action: Nach rechts laufen Priority: 2 Bewertung und Kommentare zur Regel „Nach rechts laufen“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. Dies ist damit zu begründen, dass sich das Ziel immer rechts befindet. Also ist es normalerweise sinnvoll, sich nach rechts zu begeben. Übrigens ist diese Regel auch in der Luft anwendbar und bezieht sich somit nicht nur auf das Laufen, sondern auch auf das Springen, Fliegen und Fallen nach rechts. Normalerweise ist es zwar sinnvoll nach rechts zu laufen, außer wenn sich dort ein schadendes Objekt befindet. Es wird nicht nach rechts gelaufen, wenn sich dort etwas Blockierendes befindet, da dies durch das Spiel ohne Nachteil sowieso verhindert wird. In diesem Fall dient das Verhindern der Regel eigentlich nur dazu, der Leerlauf-Regel Raum zu bieten. 37 Name: Springen Precondition: Positiv: Negativ: • Rechts ist ein Abgrund oder • rechts blockiert etwas den Weg oder • rechts ist etwas Schadendes im Weg • oben ist etwas, was blockiert oder • oben ist etwas, was schadet oder • man befindet sich schon in der Luft Action: Springen Priority: 100 Bewertung und Kommentare zur Regel „Springen“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. Das Springen über ein Hindernis oder eine Lücke ist ein wichtiger Teil in jedem Jump N Run und kann, bis auf wenige Ausnahmen, als eine gute Faustregel angewandt werden. Die Ausnahmen, die dann für das jeweilige Spiel gelten, müssen hier mit modelliert werden. Name: Sich fallen lassen Precondition: Positiv: Negativ: • Der Spieler fällt oder gleitet. • Der Spieler ist über einem haltenden Objekt. • Das Objekt ist „relativ“ nah. • Zwischen dem Spieler und dem haltenden Objekt befindet sich etwas schädliches. • Es ist unmöglich von dem haltenden Objekt weiterzukommen. Action: Fallen lassen Priority: 10 Bewertung und Kommentare zur Regel „Sich fallen lassen“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. Das „Sich fallen lassen“ entscheidet manchmal darüber, 38 ob man ein hohes Objekt erreicht oder nicht. Es ist oft sinnvoller, wenn man schon fällt, einen kleinen Abstand nach unten zu fallen, um von dort wieder abzuspringen, wenn man dann insgesamt höher kommen wird, als ohne dies zu tun. Name: Gleiten/Fliegen Precondition: Positiv: Der Spieler fällt Negativ: • Der Wechsel in den Fliegen Modus würde dem Spieler schaden (Kollisionsveränderung). • Der Spieler lässt sich absichtlich fallen. Action: Gleiten/Fliegen anschalten Priority: 10 Bewertung und Kommentare zur Regel „Gleiten/Fliegen“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. Diese Regel ist sicherlich nicht für jedes Spiel anwendbar, da es sich um eine Spezialität dieses Spiels handelt. Die Regel des „Gleitens/Fliegens“ kann natürlich auch weggelassen werden, wenn sie nicht anwendbar ist. Doch bei diesem Spiel ist es, bis auf wenige Ausnahmen, immer sinnvoller zu Gleiten/Fliegen, als zu Fallen, da man eine größere Distanz überwinden kann. Name: Gleiten/Fliegen um nicht von unten in Feuer zu springen Precondition: Spieler springt und befindet sich unter Feuer Action: Gleiten/Fliegen anschalten Priority: 10 Bewertung und Kommentare zur Regel „Gleiten/Fliegen um nicht von unten in Feuer zu springen“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. Wenn der Spieler sich direkt unter Feuer befindet und springt, kann der unmittelbare Zusammenprall damit verhindert werden, dass der Spieler in den Gleiten/Fliegen Modus wechselt, da er ab dann nicht weiter an Höhe gewinnt. Diese Regel ist nicht in jedem Spiel möglich und man muss 39 sich somit eine andere Möglichkeit überlegen, Feuer zu vermeiden, wenn dies nicht möglich ist, je nach Spiel. Name: Aufhören nach rechts zu laufen Precondition: Spieler ist links neben Feuer Action: Nach rechts Laufen ausschalten Priority: 20 Bewertung und Kommentare zur Regel „Aufhören nach rechts zu laufen“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. Da die Künstliche Intelligenz in diesem Spiel nicht aufhört, nach rechts gedrückt zu halten, ist es notwendig, einen „Button-ReleasedEvent“ zu senden, um zu verhindern, dass der Spieler in ein schadendes Objekt läuft. 3.6.1.2 Kompliziertere Regeln (essentiell, aber eventuell ineffizient) Die folgenden Regeln sind zwar komplizierter zu implementieren, aber wenn sie fehlerfrei und effizient implementiert werden, können sie eine effektive Erweiterung des Regelsatzes darstellen. Name: Nicht von oben in ein schadendes Objekt fliegen Precondition: Spieler fällt oder fliegt/gleitet mit dem Kurs auf ein schadendes Objekt Action: Finde einen alternativen Weg, bei dem man nicht auf ein schadendes Objekt fliegt. Priority: 100 Bewertung und Kommentare zur Regel „Nicht von oben in ein schadendes Objekt fliegen“: Es handelt sich zwar theoretisch um eine essentielle Regel, aber der Ansatz hat sich in der Praxis als fehlerhaft erwiesen. Die Regel wurde beim Testen in falschen Situationen angewandt und es gab enttäuschende Ergebnisse. Es hatte meist zur Folge, dass alle Leben an einer Stelle verloren wurden. Es handelt sich sicher um einen guten Gedanken, nur die Umsetzung müsste noch verbessert werden. Die richtige Erkennung, wann der Spieler in Feuer springen würde, sowie die effiziente Findung einer Alternative ist hierbei essentiell. 40 Name: Leerlaufregel Precondition: Keine Action: Einen Counter hochzählen Priority: 1 Bewertung und Kommentare zur Regel „Leerlaufregel“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. Die Leerlaufregel ist dazu da, um zu erkennen, wie lange der Charakter schon festsitzt und nichts tun kann. So kann man je nach Spiel folgende Aktionen in Betracht ziehen: • Nach längerer Zeit alternative Routen finden • die Richtung wechseln • absichtlich Suizid begehen, um weiterzukommen • Fähigkeiten benutzen • Es bestehen noch viele andere Möglichkeiten, die man je nach Besonderheiten des Spieles anwenden könnte. Name: Finde einen neuen Weg Precondition: Der „Leerlaufregelcounter“ erreicht ein gewisses Level. Nun werden Wege gesucht, mit denen man eine bessere Position erreichen könnte. Action: Den gefundenen Weg ausführen Priority: Die Priorität muss je nach erreichbaren Punkt variieren und ist meistens anderen Regeln zu bevorzugen. Bewertung und Kommentare zur Regel „Finde einen neuen Weg“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. Zwar wurde beim Testen oft keine gute Alternative gefunden. Falls sich dennoch eine (brauchbare) Alternative finden lässt, ist es eine große Bereicherung, da man auch einer Lage entfliehen kann, aus der man sonst eventuell nicht herauskommen würde. Name: Nach links laufen Precondition: Der „Leerlaufregelcounter“ erreicht ein gewisses Level. Action: Iterativ probieren, sich immer mehr nach links zu bewegen und es dann von dort erneut probieren, bis man an dem Ort vorbeigekommen ist, an dem man stecken geblieben ist. Priority: Die Priorität ist abhängig vom „Leerlaufregelcounter“. 41 Bewertung und Kommentare zur Regel „Nach links laufen“: Es hat sich beim Testen herausgestellt, dass es sich hierbei um eine essentielle Regel handelt. In sehr vielen Situationen hat diese Regel gereicht, um nicht stecken zu bleiben. Diese Regel sollte abwechselnd mit der „Finde Einen Neuen Weg“ Regel angewandt werden, in dem Fall, dass man nicht weiterkommt. Praktisch wurde es so umgesetzt, dass der „Leerlaufregelcounter“ nach unten gezählt wurde bis 0 erreicht wird. Als nächstes wurde ein Counter hochgezählt, für wie oft man stecken geblieben ist, und somit die Zeit, die man sich nach links bewegt hat, iterativ steigt. Name: Aus einem Käfig befreien Precondition: Befindet sich der Spieler an einem Ort, aus dem er in keine Richtung unbeschadet herauskommt, dann finde einen Weg, mit dem man minimalen Schaden erleidet, aber sich aus der Lage befreien kann. Action: Begehe den gefunden Weg. Priority: Priorität ist abhängig vom erlittenen Schaden und ob man wirklich aus der Situation herauskommt. Bewertung und Kommentare zur Regel „Aus einem Käfig befreien“: Es hat sich beim Testen herausgestellt, dass es sich zwar um eine essentielle Regel handelt, aber die Ausführung funktionelle Fehler hatte. Somit war es besser, diese Regel nicht einzubauen, da sie oft zu Fehlern geführt hat. Es wurde von der Künstlichen Intelligenz manchmal fälschlicherweise davon ausgegangen, dass es keinen Ausweg gibt, obwohl das nicht der Fall war. Es handelt sich zwar um einen guten Gedanken, nur die Umsetzung müsste noch verbessert werden. 3.6.2 Fortgeschrittenere Regeln für ein 2d Sidescroller Jump n Run Computerspiel Diese Regeln könnten je nach Art des Spiels nützlich sein, sind aber nicht zwingend erforderlich. Oft ändert es nichts an dem Erfolg des Spielers. Doch wenn es zum Beispiel die Vorgabe gibt, dass bestimmte Dinge aufgesammelt werden müssen, ohne die es nicht weitergeht, gäbe es hier entsprechende Regelansätze, die dafür eventuell hilfreich sind. 42 Name: Einen essentiellen Gegenstand aufsammeln Precondition: Man befindet sich an einem sicheren Ort und es gibt einen Weg zu einem essentiellen Gegenstand Action: Führe den Weg aus Priority: Extrem hoch, je nach Gefahr auf dem Weg und Wert des Gegenstandes Bewertung und Kommentare zur Regel „Einen essentiellen Gegenstand aufsammeln“: Ein Problem hierbei ist, wann die Regel nicht angewandt werden soll. Da durch sie die Performance extrem reduziert wird, wenn nach jedem Schritt überprüft wird, ob es einen Weg zum essentiellen Objekt gibt. Beim Testen der Regel gab es oft Endlosschleifen oder extreme Performance Probleme. Es ist hierbei essentiell, dass das Pathfinding in jeder Situation perfekt funktionieren können muss. Im Rastersystem ist dies zum Beispiel teilweise einfach zu ungenau, um eindeutig zu sagen, ob es auf jeden Fall möglich ist. Doch eine genaue Berechnung wäre oft zu aufwändig. Eine effiziente und korrekte Lösung für dieses Problem ist eine echte Herausforderung. Wenn diese Probleme behoben wären, wäre es jedoch eine große Bereicherung für den Regelsatz. Name: Einen helfenden Gegenstand aufsammeln Precondition: Man befindet sich an einem sicheren Ort und es gibt einen Weg zu einem helfenden Gegenstand Action: Führe den Weg aus Priority: Je nach Position, die man für das Aufsammeln aufgeben muss und je nach Wichtigkeit des Gegenstandes Bewertung und Kommentare zur Regel „Einen helfenden Gegenstand aufsammeln“: In dem Spiel, um das es hier geht, handelt es sich bei diesen Gegenständen um Blätter. Diese können eingesammelt werden, um sich Leben dazuzuverdienen. Außerdem verliert man alle Blätter, statt ein Leben, falls man Blätter hat und Schaden nimmt. Wenn man kein Blatt hat und Schaden nimmt, verliert man ein Leben. Also ist es oft nicht sinnvoll, eine starke Position aufzugeben, um ein Blatt aufzusammeln. Aber wenn man dabei nichts verliert, ist es immer sinnvoll es zu tun. Wenn man für einen Gegenstand eine gute Position aufgibt, muss man abwägen, ob er das wert ist. Ein wichtiges Kriterium für den Erfolg dieser Regel ist also das richtige „Nichtanwenden“ dieser Regel. Wenn sie nämlich in risikoreichen Situationen angewandt wird, hat das oft fatale Folgen. Die Regel hat beim Testen 43 oft dazu geführt, dass die Position verschlechtert wurde und somit der Spieler zum Beispiel in die Lava fiel, nachdem er das Blatt aufgesammelt hat. Es ist also notwendig, eine Art Risikobewertung in diese Regel einzuführen. Wie risikofreudig man ist, entscheidet über Erfolg und Misserfolg dieser Regel. Beim Testen wurden sowieso genug Blätter zufällig aufgesammelt, wenn sie einfach ignoriert wurden und wenn sie zufällig auf dem Weg waren, so dass es bessere Ergebnisse ohne diese Regel gab, als mit. Es ist eine Herausforderung, diese Regel so zu gestalten, dass sie wirklich einen Nutzen bringt. Aber wenn die Regel gut, effizient und korrekt arbeitet, sollte sie eine große Bereicherung für den Regelsatz darstellen. Name: Einen helfenden Gegenstand aus der Luft aufsammeln Precondition: Man befindet sich in der Luft und es gibt einen kurzen Weg zu einem helfenden Gegenstand Action: Führe den Weg aus Priority: Je näher desto höher Bewertung und Kommentare zur Regel „Einen helfenden Gegenstand aus der Luft aufsammeln“: Hier ist das richtige „Nichtanwenden“ der Regel eine der größten Herausforderungen. Wenn sie nämlich in zu risikoreichen Situationen angewandt wird, verliert der Spieler zu viel Position und kann somit manche Orte eventuell nicht mehr erreichen oder verliert sogar ein Leben. Auch sollte die Berechnung des Weges nur in der Ausnahme ausgeführt werden, da die Zeit in der Luft für Berechnungen extrem begrenzt ist. Denn wenn man während der Berechnung auch nur einen Pixel nach unten fällt, könnte der Weg nicht mehr gültig sein. Allgemein ist diese Regel sehr vorsichtig zu benutzen, da sie die Qualität des Regelsatzes extrem verschlechtern kann, wenn sie nicht effizient und korrekt implementiert wird. Name: Die Distanz zu einem essentiellen Gegenstand verringern Precondition: Der Spieler befindet sich zu weit weg, um einen essentiellen Gegenstand direkt zu erreichen. Aber es gibt eine Möglichkeit, näher an diesen Gegenstand zu kommen. Action: Den Weg ausführen Priority: Je näher man an dem essentiellen Gegenstand ist, desto höher die Priorität. Aber sie sollte niedriger sein, als die Priorität von „Ast Aufsammeln“ Bewertung und Kommentare zur Regel „Die Distanz zu einem essentiellen Gegenstand verringern“: Bei dieser Regel stellt sich die Frage, wann sie angewandt werden sollte und 44 wann nicht und wie man sicherstellt, dass es überhaupt möglich ist, den essentiellen Gegenstand einzusammeln. Die Umsetzung führte in der Praxis oft zu Endlosschleifen und war somit nicht wirklich brauchbar. Wenn diese Probleme behoben wären, wäre es jedoch eine große Bereicherung für den Regelsatz. Abbildung 24: Abgebildet ist ein unabwendbarer Sprung ins Feuer. Wenn man links von einem blockierenden oder schadenden Objekt springt und dann oben auch ein schadendes Objekt ist, kann man sich nicht, ohne Schaden zu nehmen, in den Fliegen/Gleiten Modus drehen, da das Objekt rechts im Weg ist. Name: Etwas wegbewegen für Drehung Precondition: Der Spieler befindet sich zu nah an einem Objekt, so dass er sich nicht drehen kann Action: Sich von dem Objekt wegbewegen Priority: Wenig Bewertung und Kommentare zur Regel „Etwas wegbewegen für Drehung“: Diese Regel basiert auf der Idee, dass man sich nicht drehen kann, um zu Fliegen, wenn man sich zu nahe an einem anderen Objekt befindet. Somit hätte man zum Beispiel das Problem, das in Abbildung 24 dargestellt ist. In diesem Fall sollte diese Regel eintreten und dem Agenten somit helfen, nicht unnötig in ein schadendes Objekt zu springen. Die Umsetzung hatte jedoch Macken, so dass die Position des Spielers oft unnötig verschlechtert wurde. Beim Testen hat sich herausgestellt, dass ohne die Regel ein viel besseres Ergebnis erzielt wurde. Da es sich um einen Sonderfall handelt und es auch nicht richtig funktioniert hat, ist diese Regel in dieser Kategorie gelandet. 45 Name: Auf den höchsten Punkt des Objektes springen Precondition: Der Spieler ist nicht am höchsten Ort des Objektes, auf dem er steht, oder kann ohne größere Probleme noch weiter nach oben kommen. Action: Nach oben gehen. Priority: Hohe Priorität, da der erreichte Punkt oft einen besseren Ausgangspunkt darstellt. Name: Auf ein höheres Objekt springen Precondition: Der Spieler würde eine höhere und somit bessere Position haben, wenn er auf das Objekt springt. Es gibt einen Weg, um dorthin zu kommen. Action: Den Weg ausführen. Priority: Die Priorität ist von der Bewertung der Positionsverbesserung abhängig. Bewertung und Kommentare zu den Regeln „Auf ein höheres Objekt springen“ und „Auf den höchsten Ort des Objektes springen“: Diese Regeln hatten das Problem, dass sie oft dazu geführt haben, dass der Spieler immer wieder in dieselbe Sackgasse gesprungen ist und somit nicht weiterkam. Man bräuchte eine weit vorausplanende Erkennung von Sackgassen. Dies effizient einzubauen, ist aber gar nicht so einfach. Es ist sicher eine gute Idee, aber die Umsetzung zeigte in der Praxis keine guten Ergebnisse. 3.6.3 Allgemeine Anmerkungen zu den Regeln Es folgen Anmerkungen, die man für das Erstellen der Regeln und eines Regelsystems bedenken sollte. 3.6.3.1 Das Durchziehen mancher Regeln Manche Regeln erfordern es, nur in Außnahmefällen, durch andere Regeln unterbrochen werden zu können. Es ist zum Beispiel oft nicht sinnvoll das „Sich fallen lassen (um auf einem Objekt zu landen)“ zu unterbrechen. Denn bevor man landet, doch noch nach rechts zu fliegen, resultiert mit dem Fallen in eine Grube. Auch die Ausführung eines gefundenen Weges sollte nicht ständig unterbrochen werden. 3.6.3.2 Das Suspendieren oder Ausschalten mancher Regeln Manche Regeln verbrauchen viel Zeit und Speicher zur Berechnung, ob die Preconditions erfüllt sind. Hier geht es vor allem um die Berechnung, ob ein Weg möglich ist. Eine gute Lösung hierfür wäre das temporäre Ausschalten 46 einer Regel oder eines Objektes für das Pathfinding. Dies sollte für eine zufällige Zeit zwischen bestimmten Grenzen erfolgen, die sich daran orientieren, wie lange man auf die Regel oder das Objekt verzichten könnte, beziehungsweise wie wichtig das Objekt oder die Regel ist. So kann man einen unnötigen aufzusammelnden Gegenstand, der tausendfach in einem Level vorkommt, getrost länger suspendieren, als bei einem essentiellen Gegenstand. Auch wichtig ist, wie sicher die Position des Spielers ist. Befindet er sich zum Beispiel direkt über einem Abgrund, sollte die Entscheidung schnell getroffen werden und nicht erst alle Möglichkeiten durchgegangen werden. Es ist also in bestimmten Situationen auch sinnvoll, manche Regeln komplett auszuschalten. 3.6.3.3 Limit setzen Die Berechnung, ob die Regel anwendbar ist, sollte bestimmte Limits nicht überschreiten. So sollte nicht der komplette Speicher aufgebraucht werden und es sollte auch nicht zu lange dauern. Wenn der Speicher also überlastet ist oder zu viel Zeit gebraucht wurde, bei der Berechnung, ob eine Precondition erfüllt ist, ist es oft ratsam, einfach abzubrechen und ein Ersatzergebnis zu liefern. 3.6.3.4 Miteinbeziehen neuentdeckter Objekte Es kann die Situation auftreten, dass ein Weg ausgeführt wird und dabei ein neues Objekt entdeckt wird. Hierbei kann es manchmal sinnvoll sein, den Weg neu zu berechnen, wenn das neu entdeckte Objekt den Weg beeinflussen könnte. 3.7 Action Performer Der Action Performer empfängt, welche Aktion ausgeführt werden soll und versucht, diese auszuführen. Wenn es ein Weg ist, erstellt er einen „PerformWay-Thread“ und übergibt den Weg. Wenn es eine einfache Aktion wie „Nach rechts bewegen“ oder „Springen“ ist, sendet er einfach ein dementsprechendes Event an den KeyListener. Dann ist es so, als würde der Spieler die Taste drücken. 3.8 Perform-Way-Thread Der „Perform-Way-Thread“ erhält einen Weg und einen Spieler und schaltet den Arbiter bei Initialisierung aus. Außerdem probiert er bis zum Erreichen des Ziels des Weges, den Abstand zwischen momentaner Lage und Ziel des Schrittes zu minimieren, indem er dementsprechende Keyboard Events an 47 den KeyListener schickt. Die Wegabschnitte sollten übrigens einen Vorschlag enthalten, welche Aktion denn zum Ziel führen soll. Doch manchmal kommt es vor, dass der Charakter vom Weg abkommt. Dann versucht der „PerformWay-Thread“ den Weg wieder zu erreichen. Falls dies nicht möglich ist, ist der Weg fehlgeschlagen. Daraufhin wird der Arbiter informiert und kann weiter arbeiten. 4 4.1 Evaluation Bewertung der praktischen Umsetzung Die praktische Umsetzungen ist insgesamt zufriedenstellend. Zwar wurde nicht jede Idee perfekt umgesetzt, die zwischendrin aufkam, aber insgesamt kann sich das Ergebnis dennoch sehen lassen. Schon nach wenigen Tagen gab es eine Version der Künstlichen Intelligenz, die sich für eine ziemlich lange Zeit nicht schlagen ließ. Sie schöpfte die Möglichkeiten, die man ohne das Planen hat, ziemlich aus. Erst nach Monaten ist es gelungen, eine Künstliche Intelligenz zu erstellen, die immer bessere Ergebnisse erzielt, als diese. Das regelbasierte System mit „Dynamic Rule Arbitration“ erwies sich als sehr hilfreich. Auch wenn es den Nachteil hat, dass nicht mehrere Regeln gleichzeitig ausführbar sind. Diesen Nachteil kann man aber auch umgehen und somit hat man ein viel übersichtlicheres und mächtigeres Werkzeug, als man hätte, wenn man nur „if-then-else“-Verschachtelungen benutzen würde. Diese würden zwar theoretisch auch alle Möglichkeiten bieten, die man mit dem Regelsystem hat, aber die Übersichtlichkeit würde dabei in größeren Projekten auf jeden Fall verloren gehen. Aber es ist trotzdem zu sagen, dass „if-then-else“-Verschachtelungen viel schneller zu annehmbaren Ergebnissen führen, als das Regelsystem. Erst nach viel Zeit und Arbeit macht sich der Vorteil der Übersichtlichkeit bemerkbar. Das Pathfinding und die Ausführung des Weges funktioniert in den meisten Fällen ohne Probleme und selbst, wenn es nicht funktioniert, entsteht kein größeres Problem, da die Ausführung des Weges dann abgebrochen wird. Das „Suspendieren oder Ausschalten mancher Regeln“, sowie das „Limit Setzen“ hilft der Performance extrem. Auch das „Miteinbeziehen neuentdeckter Objekte“ führt zu guten Ergebnissen. 48 4.2 4.2.1 Anwendbarkeit der beschriebenen Elemente Regelbasiertes System Das beschriebene regelbasierte System ist eine übersichtliche Möglichkeit, die Besonderheiten der Künstlichen Intelligenz zu verwalten. Es braucht zwar eine gewisse Zeit, bis das System erstellt wurde, aber dann lohnt es sich, da man verschiedene Regelsätze gegeneinander Testen kann. In den meisten Fällen, in denen eine Künstliche Intelligenz in einem Computerspiel gebraucht wird, ist diese Art von Decision Making ein guter Ansatz. Man sollte sich jedoch klarmachen, dass nur eine Regel gleichzeitig anwendbar ist und es notwendig ist, Regeln auszuschalten. Das größte Problem ergibt sich aus der Erstellung der genauen Definition, wann eine Regel nicht anzuwenden ist. Bei Beachtung dieser Probleme hat man als Basis ein sehr gutes System und falls man doch mehrere Regeln gleichzeitig benutzen muss, lässt sich das System auch dementsprechend umbauen. 4.2.2 Dynamic Rule Arbitration Durch die „Dynamic Rule Arbitration“ kann man Regeln abhängig von Werten priorisieren. In manchen Fällen kommt man auch ohne aus, aber es ist sicher eine Bereicherung für viele komplexere Szenarien. Auch den Zufall kann man miteinbeziehen, um die Vorhersehbarkeit des Agenten zu minimieren. Dies ist auch sinnvoll, um zu verhindern, dass der Agent immer wieder den selben Weg begeht, der nicht zielführend ist. So kann der Agent durch zufällige Veränderung auch mal einen anderen Weg probieren. 4.2.3 Pathfinding Das Pathfinding ist für manche Szenarien einfach zu komplex. Es ist immer auf Genauigkeit, aber auch auf Zeit- und Speicherbedarf, zu achten. Auch ist es oft schwieriger für den Menschen vorauszusehen, warum der Charakter sich so verhält, wenn die Künstliche Intelligenz einen „Pathfinding-Algorithmus“ enthält. Außerdem ist das Pathfinding oft sehr fehleranfällig. Des Weiteren hat sich beim Testen in den zufälligen Levels herausgestellt, dass der Charakter weniger erfolgreich war, sobald das Pathfinding eingebaut wurde. Zudem hat die Performance darunter gelitten. Insofern hat es sich eigentlich nicht rentiert, das Pathfinding einzubauen. Das liegt aber vor allem an der Komplexität, die durch das Erstellen völlig zufälliger Levels geschaffen wurde. Hierbei ist die Rasterung der Pixel extrem problematisch. Das pixelgenaue Pathfinding wäre allerdings zu teuer. Ein guter Ansatz, um sowohl Zeitbedarf, Speicherbedarf wie auch Genauigkeit dynamisch zu halten, wäre das 49 „Dynamische Pathfinding“, wie in Kapitel 3.2.3 auf Seite 31 beschrieben. 4.3 Typisch auftretende Probleme Man sollte sich im Klaren sein, dass man viele Probleme nicht so einfach in den Griff bekommt. Wichtig hierfür ist es, sich bei Bedarf, problemspezifische Informationen anzeigen lassen zu können. Außerdem sollte man die problematische Situation bewusst herbeiführen, um es zu testen. Meistens ist es sinnvoll, sich erst Tools zu schreiben, die einem zeigen, was denn das Problem ist und dann immer weiter leichte Änderungen vorzunehmen, bis es schließlich funktioniert. Übrigens sollte man auch immer dabei beachten, nichts anderes zu zerstören. Oft passiert es nämlich, dass wenn man ein Problem behebt, mehrere andere neue Probleme entstehen, da man irgendetwas anderes mit verändert hat. Typische Fehler, die bei der Erstellung dieser Künstlichen Intelligenz entstanden sind und wie sie gelöst wurden, werden im Folgenden etwas näher ausgeführt. 4.3.1 Pathfinding ergibt unmögliche Wege Das Pathfinding ergibt unmögliche Wege und scheitert bei der Ausführung oder versucht es unendlich weiter. Das ist sehr frustrierend, doch normalerweise ist dies ein Anzeichen dafür, dass etwas an dem Pathfinding nicht stimmt. Dies war oft sehr problematisch, da die Rasterung der Pixel die Genauigkeit reduzierte. Also konnte man sich laut Rasterung zum Beispiel schon in einem Objekt befinden und somit kann man ja auch weiter in die Richtung laufen, da keine neue Kante im Weg wäre. Dies ist dann natürlich nicht möglich und führt dazu, dass der Charakter stetig versucht, gegen eine Wand zu laufen. Hierbei ist es wichtig, dass man die Wegausführung nach einer Zeit abbrechen sollte, wenn es nicht erfolgreich ist. Aber besser wäre es natürlich, wenn das Pathfinding soweit optimiert wird, dass dieser Fall nicht eintreten kann. 4.3.2 Pathfinding erkennt gute Wege nicht Folgende Gründe bestehen, warum manche Wege nicht erkannt werden: • Die Rasterung ist zu ungenau. 50 • Es dauert zu lange. • Das Pathfinding hat eine Endlosschleife. • Das Pathfinding kommt einfach gar nicht auf die Idee, diesen Weg zu probieren bis es abgebrochen wird. • Der Speicher wird zu schnell gesprengt. • Der Weg wird fälschlicherweise als „nicht möglich“ erkannt. • und so weiter Grundsätzlich kann man meistens tolerieren, wenn ein Weg nicht gefunden wird, sofern dieser nicht zu essentiell ist. Doch wenn man diesen Fehler beheben will, ist es meistens extrem viel Arbeit, herauszufinden, was denn jetzt eigentlich schief gelaufen ist, da es sehr viele Möglichkeiten gibt. 4.3.3 Der Agent kommt bei der Ausführung vom Weg ab Normalerweise sollte es nicht passieren, dass der Agent bei der Ausführung vom Weg abkommt. Doch manchmal ist der Grund zum Beispiel die Ungenauigkeit durch die Rasterung der Pixel. Vor allem beim Abspringen und bei der Flugbahn gibt dies manchmal Probleme. Die Lösung für das Problem sah folgendermaßen aus: Bei der Ausführung des Weges wurde überprüft, ob man sich auf dem Weg befindet oder nicht. Wenn nicht, wird versucht, die Distanz zu verringern. Hierbei gibt es sehr viele Sonderfälle, die dann je nach Spiel anders aussehen müssen. Oft ist es sinnvoll, einfach dieselbe Aktion wie davor weiterzuführen, aber manchmal muss man auch zurück auf den Weg kommen. Und wieder in anderen Fällen ist es sinnvoll, das Pathfinding abzubrechen. Am besten wäre allerdings, wenn dies schon im Voraus nicht passieren kann, also wenn zum Beispiel der Weg genauer berechnet wird. 4.3.4 Pathfinding dauert zu lange Wenn das Pathfinding zu lange dauert, sollte man oft abbrechen und ein weiteres Pathfinding zu diesem Objekt für eine Zeit abschalten, weil die Performance ansonsten einfach zu sehr belastet wird. Eine weitere Möglichkeit 51 wäre es auch, stattdessen einen schnelleren Algorithmus zu benutzen, wie den A* Algorithmus, oder die Kombination von A* Algorithmus und Tiefensuche, wie in Kapitel 3.3.2 auf Seite 33 beschrieben. Auch das Anwenden des dynamischen Pathfindings (siehe Kapitel 3.2.3 auf Seite 31) kann hier helfen. Eine weitere Optimierungsmöglichkeit ist das richtige Lenken des Pathfindings, sowie das Einbeziehen typischer Bewegungsmuster. Es ist zum Beispiel oft wahrscheinlich, dass man sich weiter in dieselbe Richtung bewegen sollte. Auch ein Sprung sollte oft zu Ende ausgeführt werden, wenn kein Objekt im Weg ist und so weiter. 4.3.5 Pathfinding sprengt den Speicher Der Speicher wird vor allem beim A* Algorithmus manchmal gesprengt. Eine Möglichkeit, das Problem zu lösen, wäre das Pathfinding einfach abzubrechen. Eine weitere Möglichkeit wäre es auch, wenn der Speicher gesprengt wird, also try{ } catch(StackOverFlowError e){ }, stattdessen einen speichereffizienteren Algorithmus zu benutzen, wie den Tiefensuchalgorithmus oder eine Heuristik. Alternativ könnte man auch die Kombination von A* Algorithmus und Tiefensuche benutzen, wie in Kapitel 3.3.2 auf Seite 33 beschrieben. Noch eine Möglichkeit wäre es, die Heuristik stärker zu gewichten, als den bisherigen Weg, wie bei dem dynamischen Pathfinding (siehe Kapitel 3.2.3 auf Seite 31) beschrieben. 4.3.6 Das Ausführen einer Regel schlägt fehl Dies tritt meistens in Verbindung mit Pathfinding auf, wie in Kapitel 4.3.1 auf Seite 50 beschrieben. In seltenen Fällen ist etwas anderes der Grund. Das lässt sich aber dann meistens einfach beheben, da man relativ genau erkennt, warum jetzt nicht die Aktion ausgeführt wurde. Oft handelt es sich dann um Verwechselungen oder kopierte Passagen, die noch nicht verändert wurden. 4.3.7 Endlosschleifen Meistens ist der Grund hierfür, entweder das Pathfinding, wie in Kapitel 52 4.3.1 auf Seite 50 beschrieben, oder dass etwas kopiert und noch nicht verändert wurde. Ein weiterer Grund ist oft das Verwechseln zweier Zähler in geschachtelten „for-Schleifen“, wie zum Beispiel: for ( int i =0; i < list . size (); i ++){ for ( int j =0; j < list . size (); i ++){ } } Hierbei muss bei der zweiten „for-Schleife“ einfach das i durch ein j ersetzt werden und schon hat man das Ergebnis. Ähnliche Fehler treten sehr häufig auf und die Behebung ist oft extrem schwierig, da man die genaue Stelle finden muss. Aber wenn man nochmal jeden Zähler in dem entsprechenden Teilbereich, der wohl verantwortlich ist, überprüft, sollte man das Problem schnell in den Griff bekommen. Vor allem die Frage, ob er auch wirklich das Abbruchkriterium erreichen kann, beziehungsweise ob auch der richtige Zähler hochgezählt wird, sollte überprüft werden. 4.3.8 Regeln behindern sich gegenseitig Meistens ist das Durchziehen der Regel, wie in Kapitel 3.6.3.1 auf Seite 46 beschrieben, eine gute Regel für dieses Problem. Aber manchmal ist es sinnvoll, die Spring-Regel für den Fall, dass man steckengeblieben ist, zufällig zu aktivieren oder zu deaktivieren, so dass man auf Dauer alle Möglichkeiten durchprobieren kann. Wenn es zum Beispiel darum geht, dass der Charakter stecken geblieben ist und er nur herauskommt, wenn er nach links läuft und nicht springt beziehungsweise doch springt. Auch andere Regeln sollten zufällig an- und ausgeschaltet werden, so dass jede Kombination von an- und ausgeschalteten Regeln theoretisch erreicht werden kann, um aus jeder Situation herauszukommen. Eine ähnliche Möglichkeit wäre die Nutzung des Modulos auf Primzahlen. So kann man zum Beispiel eine Regel ausschalten, wenn der Rest der Teilung durch 3 eine 0 ergibt. Eine andere Regel wird ausgeschalten, wenn die Teilung durch 7 eine 3 ergibt. Man sollte sich aufschreiben, welche Primzahlen man nun schon verwendet hat. Damit ist garantiert, dass jede Kombination auch wirklich erreicht wird. 53 4.3.9 Der Charakter läuft durch Objekte/Kollisionsprobleme Sobald sich ein Charakter schon in einem Objekt befindet, in das er eigentlich nicht kommen kann, ist es normalerweise nicht sinnvoll, ihm die Möglichkeit zu nehmen, sich herauszumanövrieren, da er sonst nicht weiterspielen kann. Deshalb sollte man ihm die Möglichkeit geben, herauszukommen, auch wenn er davon einen unfairen Vorteil hat. Trotzdem sollte man versuchen, dass das nicht zu oft vorkommt. Dies passiert zum Beispiel, wenn sich die Kollisionsgröße des Charakters verändert, wie es beim Wechseln in den Gleiten/Fliegen-modus der Fall ist, bei dem sich die Kollision um 90◦ dreht. Aber auch wenn das Level zufällig erstellt wird, kann der Charakter direkt innerhalb eines Blockes starten. Außerdem wenn er zum Beispiel stirbt und dann an einem anderen Ort wiederbelebt wird, kann er auch in einem anderen Objekt starten. Wenn dies alles nicht der Fall ist, ist wohl die Kollisionsabfrage fehlerhaft. Manchmal hilft es, zum Beispiel bei Kollision zwischen A und B, auch die Kollision zwischen B und A abzufragen oder die Kollisionsabfrage etwas zu erweitern. 4.3.10 Der Charakter „betrügt“ Wenn sich der Charakter durch feste Objekte durchbewegt, liegt das meistens an der Kollisionsabfrage, wie in Kapitel 4.3.9 auf Seite 54 beschrieben. Ansonsten sollte das eigentlich nicht der Fall sein. In anderen Fällen muss man den Betrug analysieren und überlegen, wie man das Problem lösen kann. Meistens liegt es aber an dem Spiel selbst und nicht an der Künstliche Intelligenz. Eine weitere Möglichkeit ist, dass die Künstliche Intelligenz einfach zu schnell Befehle sendet und das Spiel darauf nicht ausgelegt ist und man somit zum Beispiel das Fallen umgehen kann. Dies liegt aber wiederum eigentlich am Spiel selbst. 4.3.11 Der Charakter sitzt fest Nun stellt sich allerdings die Frage, was zu tun ist, wenn der Charakter festsitzt. Hierfür gibt es mehrere Ansätze, die zusammen schon die meisten Probleme lösen können: • Das „Nach Links laufen“, wie in Kapitel 3.6.1.2 auf Seite 41 beschrieben 54 • die „Finde Einen Neuen Weg“-Regel, wie auf Seite 41 beschrieben • die „Leerlaufregel“, wie auf Seite 41 beschrieben • die „Aus einem Käfig Befreien“-Regel, wie auf Seite 42 beschrieben 4.3.12 Ist ein Objekt im Weg / Erreichbarkeit von Objekten Hier geht es um das Pathfinding durch die optimale Springfunktion, wie in Kapitel 3.2.1.2 auf Seite 29 beschrieben. Dieses ist auch vollkommen ausreichend, sogar wenn ein Objekt im Weg ist. Aber falls dann wieder ein Objekt im Weg ist, auf dem neuen Weg, der berechnet wurde, um dem ersten Objekt auszuweichen, gibt es sehr viele Möglichkeiten zu handeln. Diese lassen sich nur sehr schwer alle vollkommen durchspielen, da dies immer wieder vorkommen kann. In solchen Fällen wäre es sinnvoller, mit dem Pathfinding mit gerasterten Pixeln (Kapitel 3.2.2 auf Seite 30) oder mit dem dynamischen Pathfinding (Kapitel 3.2.3 auf Seite 31) weiterzuarbeiten. 4.3.13 Der Charakter könnte besser handeln Dies ist normalerweise ein gutes Indiz dafür, dass eine neue Regel hinzugefügt werden sollte. Man sollte sich folgende Fragen beantworten: • Was soll getan werden? • Warum würde man das so tun? • Auf was basieren diese Entscheidungen? • Wann würde man es tun? • Wann würde man es nicht tun? • Wie wichtig ist es, genau so vorzugehen? • Wie könnte die Künstliche Intelligenz eine solche Situation erkennen? • Wie erkennt die Künstliche Intelligenz, dass die Regel nicht angewandt werden sollte? 55 Wenn man sich diese Fragen stellt und die Antworten zu einer oder mehreren Regeln umformuliert, sollte man testen, ob die Künstliche Intelligenz nun in diesen Situationen richtig reagiert und auch nicht in anderen Situationen plötzlich Fehler macht. Das Zweite ist oft das größere Problem. 4.3.14 Das Hinzufügen der Regel ergibt schlechtere Ergebnisse Das hat meistens den Grund, dass die Regel zu oft angewandt wird, beziehungsweise in bestimmten Situationen nicht angewandt werden sollte. Dieses Problem kann man eventuell mit dem Suspendieren/Ausschalten, wie in Kapitel 3.6.3.2 auf Seite 46 beschrieben, oder mit dem Limit setzen, wie in Kapitel 3.6.3.3 auf Seite 47 beschrieben, in den Griff bekommen. 5 5.1 Resumé Erreicht Es wurden viele verschiedene Ansätze beschrieben, um eine Künstliche Intelligenz in einem Jump N Run Computerspiel zu erstellen. Sowohl das Treffen von Entscheidungen, wie das Finden von Wegen in zufälligen Levels, wurde ausführlich erklärt. Es wird garantiert, dass der autonome Agent einen Spieler simuliert, ohne irgendwelche unfairen Vorteile zu bekommen. Nur bisher gesehene Objekte werden in Betracht gezogen. Damit der Agent Aktionen ausführen kann, werden wie bei einem Spieler Tastatur und Maus durch Events simuliert. Die Graphen zur Wegfindung werden automatisch erstellt. Es gibt kaum andere Literatur in diese Richtung und wenn, dann bezieht sie sich oft nur auf das Erstellen von Gegnern, auf andere Genres oder Ähnlichem. Den größten Bezug zu dieser Arbeit hatten lediglich Wettbewerbe, bei denen es darum ging, eine Künstliche Intelligenz für ein Jump N Run Computerspiel zu schreiben ([10], [11]). 5.2 Ausblick Die Perfektionierung des Pathfindings, sowie die Erweiterung oder Veränderung der Regelsätze, wären Herausforderungen, denen man sich noch stellen kann. Eine weitere Herausforderung wäre wohl das Anpassen und Einbauen 56 dieser Künstlichen Intelligenz in ein Spiel, beziehungsweise die Erweiterung dieses Spiels, so dass es Spaß macht und eventuell sogar kommerziell erfolgreich wird. Hierfür darf die Performance einerseits nicht merkbar durch die Künstliche Intelligenz verändert werden. Andererseits jedoch soll sie auch für den Spieler in irgendeiner Weise das Spiel verbessern. Auch die Herausforderung der Entscheidung, was der Spieler dann für eine Rolle übernehmen soll, wenn die eigentlich gedachte typische Jump N Run Rolle schon übernommen ist, ist eine weitere Aufgabe. Man könnte einerseits dem Spieler dieselbe Rolle geben, aber andererseits könnte man ihm auch eine völlig neue Rolle zukommen lassen. Es ist eine echte Herausforderung, hierfür ein gutes Konzept zu entwickeln. Aber auf jeden Fall wäre das ein erfrischender neuer Wind in der Spielebranche und könnte zu einem echten Erfolg werden. Literatur [1] Funge, J. (2004): Artificial Intelligence For Computer Games. Wellesley, Massachusetts: A K Peters, Ltd. [2] Millington, I. & Funge, J. (2009): Artificial Intelligence For Games (2nd ed.). Burlington: Morgan Kaufmann Publishers, Elsevier Inc. [3] Saltzman, Marc (1999): Game Design Die Geheimnisse der Profis. München: X-Games, Markt & Technik Verlag. [4] http://www.flugsimulator.de/aerosoft62/ibizax_6.jpg, aufgerufen am 09.09.2012. zuletzt [5] http://zfs-forschung.de/pageID_2964358.html, zuletzt aufgerufen am 09.09.2012. [6] http://pille.iwr.uni-heidelberg.de/~bogynastja/dijkstra2. gif, zuletzt aufgerufen am 09.09.2012. [7] http://de.wikipedia.org/wiki/Artillery_%28Computerspiel%29, zuletzt aufgerufen am 09.09.2012. [8] http://www.ai-blog.net/archives/000152.html, zuletzt aufgerufen am 12.09.2012. [9] http://en.wikipedia.org/wiki/Strong_ai, zuletzt aufgerufen am 10.09.2012. 57 [10] http://julian.togelius.com/mariocompetition2009/, zuletzt aufgerufen am 13.09.2012. [11] http://apo-games.de/apoMario/, zuletzt aufgerufen am 13.09.2012. [12] http://www.forbes.com/sites/alexknapp/2012/03/20/ ray-kurzweils-predictions-for-2009-were-mostly-inaccurate/, zuletzt aufgerufen am 10.09.2012. 58 Ich erkläre hiermit gemäß § 17 Abs. 2 APO, dass ich die vorstehende Bachelorarbeit selbstständig verfasst und keine anderen als die angegebenen Quellen und Hilfsmittel benutzt habe. ........................................... Datum ........................................................................... Unterschrift 59