Ich arbeite an einem Spiel mit Karten, die Schloss- und Schlüsselrätseln ähneln . Die KI muss zu einem Ziel navigieren, das sich möglicherweise hinter einer verschlossenen roten Tür befindet, aber der rote Schlüssel befindet sich möglicherweise hinter einer verschlossenen blauen Tür usw.
Dieses Puzzle ähnelt einem Dungeon im Zelda-Stil.
Um zum Ziel zu gelangen, musst du den Boss besiegen. Dazu musst du über die Grube gehen, die Feder einsammeln und den Schlüssel einsammeln
Zelda-Dungeons sind in der Regel linear. Allerdings muss ich das Problem im allgemeinen Fall lösen. So:
- Für das Ziel kann ein Schlüsselsatz erforderlich sein. Vielleicht müssen Sie entweder den roten oder den blauen Schlüssel holen. Oder es könnte eine unverschlossene Tür in der Ferne geben!
- Es könnte mehrere Türen und Schlüssel einer Art geben. Es können sich beispielsweise mehrere rote Schlüssel auf der Karte befinden. Wenn Sie einen sammeln, erhalten Sie Zugriff auf alle roten Türen.
- Das Ziel ist möglicherweise nicht erreichbar, da sich die richtigen Schlüssel hinter verschlossenen Türen befinden
Wie würde ich auf einer solchen Karte eine Wegfindung durchführen? Wie würde das Suchdiagramm aussehen?
Hinweis: Der letzte Punkt zum Erkennen unzugänglicher Ziele ist wichtig. Ein * ist beispielsweise äußerst ineffizient, wenn das Ziel nicht erreichbar ist. Damit möchte ich effizient umgehen.
Angenommen, die KI weiß, wo sich alles auf der Karte befindet.
quelle
Antworten:
Die Standardpfadfindung ist gut genug - Ihre Bundesstaaten sind Ihr aktueller Standort und Ihr aktueller Bestand. "Umziehen" bedeutet entweder, Räume zu wechseln oder das Inventar zu wechseln. Nicht behandelt in dieser Antwort, aber nicht zu viel zusätzlicher Aufwand, ist das Schreiben einer guten Heuristik für A * - es kann die Suche wirklich beschleunigen, indem es bevorzugt, Dinge aufzuheben, anstatt sich von ihr wegzubewegen, und bevorzugt, eine Tür in der Nähe des Ziels aufzuschließen über die Suche nach einem weiten Weg, etc.
Diese Antwort hat viele positive Stimmen erhalten, seitdem sie auf den Markt kam, und verfügt über eine Demo. Für eine viel optimierte und spezialisierte Lösung sollten Sie jedoch auch die Antwort /gamedev/ lesen / a / 150155/2624
Vollständig funktionsfähiger Javascript Proof of Concept (siehe unten). Entschuldigen Sie die Antwort als Code-Dump - ich hatte sie tatsächlich implementiert, bevor ich überzeugt war, dass sie eine gute Antwort ist, aber sie scheint mir ziemlich flexibel zu sein.
Denken Sie beim Überlegen der Pfadfindung zunächst daran, dass die Hierarchie der einfachen Algorithmen zur Pfadfindung wie folgt lautet:
In unserem Fall können wir Djikstra oder A * verwenden, um unser Problem zu lösen, indem wir lediglich einen "Zustand" als "Ort + Inventar" und "Entfernungen" als "Bewegung oder Verwendung von Gegenständen" codieren.
Hier ist ein aktueller Code, der Ihre Beispielstufe demonstriert. Das erste Snippet dient nur zum Vergleich - springen Sie zum zweiten Teil, wenn Sie die endgültige Lösung sehen möchten. Wir beginnen mit einer Djikstra-Implementierung, die den richtigen Pfad findet, aber wir haben alle Hindernisse und Schlüssel ignoriert. (Probieren Sie es aus, Sie können sehen, dass es nur Linien für das Ziel sind, von Raum 0 -> 2 -> 3-> 4-> 6-> 5)
Wie fügen wir diesem Code also Elemente und Schlüssel hinzu? Einfach! Anstelle jedes "Zustandes" beginnt nur die Raumnummer, es ist jetzt ein Tupel des Raumes und unser Inventarzustand:
Die Übergänge ändern sich nun von einem (Kosten-, Raum-) Tupel zu einem (Kosten-, Zustands-) Tupel, sodass sowohl das Verschieben in einen anderen Raum als auch das Aufnehmen eines Gegenstands codiert werden können.
Schließlich nehmen wir einige geringfügige typbezogene Änderungen an der Djikstra-Funktion vor (z. B. stimmt sie immer noch nur mit einer Zielraumnummer statt mit einem vollständigen Status überein), und wir erhalten unsere vollständige Antwort! Beachten Sie, dass das gedruckte Ergebnis zuerst zu Raum 4 geht, um den Schlüssel aufzuheben, dann zu Raum 1, um die Feder aufzuheben, und dann zu Raum 6, um den Boss zu töten und dann zu Raum 5).
Theoretisch funktioniert dies sogar mit BFS, und wir haben die Kostenfunktion für Djikstra's nicht benötigt, aber wenn wir die Kosten haben, können wir sagen: "Einen Schlüssel abzuholen ist mühelos, aber gegen einen Boss zu kämpfen ist wirklich schwer, und wir wollen lieber zurück 100 Schritte statt gegen den Boss zu kämpfen, wenn wir die Wahl hätten ":
quelle
Rückwärts A * erledigt den Trick
Wie in dieser Antwort auf die Frage nach der Vorwärts- und Rückwärtspfadfindung erörtert , ist die Rückwärtspfadfindung eine relativ einfache Lösung für dieses Problem. Dies funktioniert sehr ähnlich wie GOAP (Goal Oriented Action Planning), bei dem effiziente Lösungen geplant und ziellose Fragen minimiert werden.
Am Ende dieser Antwort habe ich eine Aufschlüsselung, wie es mit dem von Ihnen angegebenen Beispiel umgeht.
Im Detail
Wegfindung vom Ziel zum Start. Wenn Sie bei Ihrer Wegfindung auf eine verschlossene Tür stoßen, haben Sie einen neuen Zweig zu Ihrer Wegfindung, der durch die Tür verläuft, als wäre sie nicht verschlossen, und der Hauptzweig sucht weiter nach einem anderen Pfad. Der Zweig, der durch die Tür geht, als wäre er unverschlossen, sucht nicht mehr nach dem KI-Agenten - er sucht jetzt nach einem Schlüssel, mit dem er die Tür passieren kann. Bei A * ist die neue Heuristik die Entfernung zum Schlüssel + Entfernung zum KI-Agenten, anstatt nur die Entfernung zum KI-Agenten.
Wenn der Zweig mit der nicht gesperrten Tür den Schlüssel findet, sucht er weiter nach dem KI-Agenten.
Diese Lösung wird etwas komplizierter, wenn mehrere funktionsfähige Schlüssel verfügbar sind, Sie können jedoch entsprechend verzweigen. Da die Zweige ein festes Ziel haben, können Sie dennoch eine Heuristik verwenden, um die Pfadfindung (A *) zu optimieren, und unmögliche Pfade werden hoffentlich schnell abgeschnitten - wenn kein Weg an der verschlossenen Tür vorbei führt, führt der Zweig nicht Wenn Sie nicht durch die Tür gehen, gehen Ihnen die Optionen schnell aus und der Zweig, der durch die Tür geht und nach dem Schlüssel sucht, geht von alleine weiter.
Wenn eine Vielzahl praktikabler Optionen zur Verfügung steht (mehrere Schlüssel, andere Elemente zur Umgehung der Tür, langer Weg um die Tür), werden natürlich viele Zweige beibehalten, die die Leistung beeinträchtigen. Sie finden aber auch die schnellste Option und können diese verwenden.
In Aktion
In Ihrem konkreten Beispiel: Wegfindung vom Ziel zum Start:
Wir stoßen schnell auf eine Cheftür. Zweig A geht weiter durch die Tür und sucht nach einem Boss zum Kämpfen. Zweig B bleibt im Raum stecken und verfällt bald, wenn er keinen Ausweg findet.
Ast A findet den Boss und sucht nun den Start, trifft aber auf eine Grube.
Zweig A geht weiter über die Grube, sucht nun aber nach der Feder und zieht dementsprechend eine Bienenlinie in Richtung der Feder. Zweig C wird erstellt, der versucht, sich in der Grube zurechtzufinden, verfällt jedoch, sobald er nicht mehr in der Lage ist. Das oder es wird für eine Weile ignoriert, wenn Ihre A * -Heuristik feststellt, dass Zweig A immer noch sehr vielversprechend aussieht.
Zweig A trifft auf die verschlossene Tür und geht durch die verschlossene Tür, als wäre sie unverschlossen, aber jetzt sucht er nach dem Schlüssel. Zweig D geht ebenfalls durch die verschlossene Tür und sucht immer noch nach der Feder, aber dann sucht er nach dem Schlüssel. Dies liegt daran, dass wir nicht wissen, ob wir zuerst den Schlüssel oder die Feder finden müssen. In Bezug auf die Wegfindung befindet sich der Start möglicherweise auf der anderen Seite dieser Tür. Zweig E versucht, einen Weg um die verschlossene Tür zu finden, und schlägt fehl.
Zweig D findet schnell die Feder und sucht weiter nach dem Schlüssel. Es darf wieder durch die verschlossene Tür gehen, da es immer noch nach dem Schlüssel sucht (und sich in der Zeit rückwärts bewegt). Aber sobald es den Schlüssel hat, kann es die verschlossene Tür nicht passieren (da es die verschlossene Tür nicht passieren konnte, bevor es den Schlüssel gefunden hat).
Zweig A und D konkurrieren weiter, aber wenn Zweig A den Schlüssel erreicht, sucht er nach der Feder und kann die Feder nicht erreichen, weil sie wieder durch die verschlossene Tür gehen muss. Zweig D hingegen richtet seine Aufmerksamkeit beim Erreichen des Schlüssels auf den Start und findet ihn ohne Komplikationen.
Zweig D gewinnt. Es hat den umgekehrten Weg gefunden. Der letzte Pfad ist: Start -> Schlüssel -> Feder -> Boss -> Ziel.
quelle
Bearbeiten : Dies ist aus der Sicht einer KI geschrieben, die darauf aus ist, ein Ziel zu erkunden und zu entdecken, und die die Position von Schlüsseln, Schlössern oder Zielen nicht im Voraus kennt.
Nehmen Sie zunächst an, dass die KI eine Art Gesamtziel hat. ZB "Find the Boss" in Ihrem Beispiel. Ja, du willst es schlagen, aber es geht wirklich darum, es zu finden. Angenommen, es hat keine Ahnung, wie es zum Ziel kommt, nur, dass es existiert. Und es wird es wissen, wenn es es findet. Sobald das Ziel erreicht ist, kann die KI aufhören, an der Lösung des Problems zu arbeiten.
Außerdem werde ich hier den Oberbegriff "Schloss" und "Schlüssel" verwenden, auch wenn es eine Kluft und eine Feder sein könnte. Das heißt, Feder "öffnet" den Abgrund "Sperre".
Lösungsansatz
Es scheint, als würdest du zuerst mit einer KI beginnen, die im Grunde genommen ein Labyrinthforscher war (wenn du deine Karte als Labyrinth ansiehst). Das Erkunden und Kartieren aller möglichen Orte wäre der Hauptfokus der KI. Es könnte lediglich auf etwas Einfachem basieren, wie "Gehe immer zu dem nächsten Pfad, den ich gesehen, aber noch nicht besucht habe."
Während der Erkundung treten jedoch einige Regeln in Kraft, die die Priorität ändern könnten ...
Ein Hinweis zu diesem letzten Punkt. Wenn es zwischen dem Auschecken eines nicht erkundeten Bereichs, den es zuvor gesehen (aber nicht besucht) hat, und einem nicht erkundeten Bereich hinter einem neu entsperrten Pfad wählen muss, sollte der neu entsperrte Pfad die Priorität haben. Dort gibt es wahrscheinlich neue Schlüssel (oder Schlösser), die nützlich sein werden. Dies setzt voraus, dass ein gesperrter Pfad wahrscheinlich keine sinnlose Sackgasse ist.
Erweiterung der Idee mit "abschließbaren" Schlüsseln
Sie könnten möglicherweise Schlüssel haben, die ohne einen anderen Schlüssel nicht genommen werden können. Oder sozusagen gesperrte Schlüssel. Wenn Sie Ihre alten Kolossalen Höhlen kennen, benötigen Sie den Vogelkäfig, um den Vogel zu fangen - den Sie später für eine Schlange benötigen. Sie "entsperren" also den Vogel mit dem Käfig (der den Weg nicht blockiert, aber ohne den Käfig nicht aufgenommen werden kann) und "entsperren" dann die Schlange (die Ihren Weg blockiert) mit dem Vogel.
Also einige Regeln hinzufügen ...
Ich werde mich nicht einmal damit befassen, wie das Tragen eines bestimmten Schlüssels die Wirkung eines anderen Schlüssels zunichte machen könnte (Colossal Caves, Rute erschreckt den Vogel und muss fallen gelassen werden, bevor der Vogel aufgenommen werden kann, wird aber später benötigt, um eine magische Brücke zu bauen). .
quelle