Ich entwickle eine KI für ein Strategiespiel (denken Sie an Final Fantasy Tactics) und habe Probleme, das Design der KI zu entwickeln. Mein Hauptproblem besteht darin, herauszufinden, welches das optimale ist.
Lassen Sie mich zunächst die Priorität der Maßnahmen beschreiben, die die KI ergreifen soll:
Töte die nächste Spielereinheit
Erfülle die primäre Anweisung (töte alle Spielereinheiten, töte die Zieleinheit, überlebe x Runden)
- Verbündete Einheit / Zauberpuffer heilen
Jetzt kann die KI ihrerseits Folgendes tun:
Bewegen -> {Angriff / Fähigkeit / Gegenstand} (entweder Angriff oder Fähigkeit oder Gegenstand)
{Angriff / Fähigkeit / Gegenstand} -> Bewegen
Gehen Sie näher heran (wenn sich die Ziele nicht in Reichweite befinden)
- {Angriff / Fähigkeit / Gegenstand} (falls kein Zug verfügbar ist)
Anmerkungen
Fähigkeiten haben verschiedene Bereiche / Effekte / Kosten / Effekte. Jede ai-Einheit hat vielleicht 5-10 Fähigkeiten zur Auswahl. Die KI wird das Töten der Sicherheit vorziehen, es sei denn, ihre Anweisung lautet, x Runden zu überleben. Es ist auch nicht wichtig, dass Fähigkeiten viel kosten. Während ein Spieler einen großen Zauber für später speichern möchte, wird die KI ihn höchstwahrscheinlich so schnell wie möglich verwenden.
Die Bewegung erfolgt auf einem (hexadezimalen) Gitter
Anzahl der Spielereinheiten: 3-6
Anzahl der ai-Einheiten: 3-7 oder mehr. Wahrscheinlich max 10.
KI und Spieler steuern abwechselnd EINE Einheit, anstatt alle gleichzeitig.
Die Plattform ist Android (wenn das Programm nach einiger Zeit nicht reagiert, wird ein Popup mit der Aufschrift "Beenden oder Warten erzwingen" angezeigt - was wirklich schlecht aussieht!).
Nun kommen die Fragen:
Die beste Fähigkeit wäre offensichtlich die, die die meisten Ziele mit dem größten Schaden trifft. Da jede Fähigkeit unterschiedliche Reichweiten hat, weiß ich nicht, ob sie sich in Reichweite befinden, ohne jeden möglichen Ort zu erkunden, an den ich mich bewegen kann.
Eine Lösung wäre, alle möglichen Orte zu durchlaufen, an die man sich bewegen kann, um den optimalen Angriff an diesem Ort zu bestimmen - was mir eine Liste der optimalen Bewegungen für jeden Ort gibt. Wählen Sie dann das Optimum aus der Liste aus und führen Sie es aus. Dies wird jedoch viel CPU-Zeit in Anspruch nehmen. Gibt es eine bessere Lösung?
Meine derzeitige Idee ist es, so nah wie möglich an die nächste, größte Gruppe von Menschen heranzukommen und von dort aus den optimalen Angriff / die optimale Fähigkeit zu bestimmen. Ich denke, dies wäre viel weniger Arbeit für die CPU und würde dennoch weitreichende Angriffe ermöglichen. Es ist nicht optimal, aber die KI wird immer noch "klug" erscheinen.
Sonstige Hinweise / Fragen:
- Überdenke / kompliziere ich es? Bessere Lösung? Ich bin offen für alle möglichen Vorschläge
- Ich habe mir die Zauberfrage angesehen , aber sie berücksichtigt nicht die Bewegung. Verwenden Sie diesen Algo also vielleicht für jeden möglichen Bewegungsort? In der Top-Antwort wurde erwähnt, dass es nicht gut für Wirkungsbereiche und Gruppenkämpfe geeignet ist - erfordert es also möglicherweise weitere Anpassungen?
- Bitte , wenn Sie eine Grafik / Baum erwähnen, lassen Sie mich wissen im Grunde , wie es zu benutzen. ZB bedeutet Knoten Fähigkeit, Stufe entspricht Schaden, dann suchen Sie nach dem tiefsten Knoten.
Im Laufe der Jahre habe ich 3 Spiel-AIs geschrieben, die alle ein respektables Spiel spielten.
Zwei der Fälle hatten begrenzte Optionen pro Runde und so erkundete ich alle Möglichkeiten und bewertete die resultierenden Positionen - ich änderte die Tiefe, die ich suchte, basierend auf der Schwierigkeit und es dauerte nicht sehr viele Schichten, um einen recht respektablen Gegner zu machen. Ich könnte ein paar Schichten nach unten bekommen und in ein oder zwei Sekunden immer noch eine Antwort haben, und das war auf einigen ziemlich alten Prozessoren. (All dies war, bevor Windows vor Ort war.) Die Qualität der Positionsanalyse ist bei Verwendung dieses Ansatzes SEHR wichtig.
Der dritte Fall erlaubte keine solche Analyse, da die Anzahl der möglichen Bewegungen pro Umdrehung die Teilchen im Universum leicht überschreiten könnte. Es war eine Art Risikobereich mit einer Reihe von Armeen, aber Sie konnten eine beliebige Anzahl von Zügen pro Spielzug ausführen, wobei der Schlüsselfaktor für Züge einige Zeit in Anspruch nahm. Eine Provinz nebenan nahm in der Regel 1 Runde, eine auf der anderen Seite der Karte 9 Runden.
Ich habe hier einen ganz anderen Ansatz gewählt. Ich entschied, wie viel Prozent der Streitkräfte der Verteidigung zugewiesen werden sollten, und teilte diese basierend auf dem Wert des Territoriums und der geschätzten feindlichen Bedrohung zu. (Während Sie sehen konnten, welche Streitkräfte Ihr Gegner bewegte, konnten Sie nicht sehen, wohin sie gingen - es wurde davon ausgegangen, dass Der Mensch würde seine Kräfte irgendwo konzentrieren und vermutete, dass es viel wahrscheinlicher ist, dass sie alle auf einmal ankommen, als Stück für Stück.) Alles, was nicht zur Verteidigung benötigt wurde, wurde für Angriffe verfügbar. Ich habe mir jedes mögliche Ziel angesehen und berechnet, was nötig ist, um eine gute Chance zu haben, es schnell zu erreichen (ein langwieriger Kampf würde im Grunde die gesamte Produktion zerstören), und eine Reihe von Angriffsbefehlen dafür generiert. Der Wert der Bestellung war der Wert der Provinz, Die Kosten waren die Anzahl der Armee / Runden, die für den Angriff eingesetzt wurden. Wählen Sie den höchsten Wert und führen Sie die Befehle aus. Wiederholen Sie diesen Vorgang, bis die verfügbaren Kräfte nichts mehr aufnehmen können. Die Ausführungszeit war trivial.
Ich hoffe, ich habe Ihnen hier einige Ideen gegeben.
quelle
Ihr Hinweis zum Beenden / Warten deutet darauf hin, dass Sie die gesamte Verarbeitungsarbeit für den Hauptthread der Anwendung ausführen. Sie können den "denkenden" Teil Ihrer KI auf einen Arbeitsthread verlagern, während der Hauptthread eine KI im Spiel anzeigt, die im Spiel in Betracht gezogen wird, vorausgesetzt, das SDK des Android bietet ausreichend Thread-Unterstützung (was meiner Meinung nach vorhanden sein muss). .. "UI wird aber sonst normal gerendert.
Natürlich gibt es gute Gründe, dies nicht tun zu wollen, zum Beispiel, dass die KI sowieso nicht so lange dauert, weil sich der Spieler langweilen wird.
Was Ihre eigentliche Frage betrifft, so ist Ihre "aktuelle Idee" zwar umsetzbar, aber sehr einfach. Es ist jedoch ein guter Ausgangspunkt. Es ist ein System, in dem die KI rein ergebnisorientiert ist und versucht, maximal einen Wert (Schaden) zu erreichen. Weitere Optionen sind ein zielgerichteter Ansatz, bei dem Sie ein Ziel aus dem gegnerischen Team auswählen (zufällig eines mit den meisten HP, eine Kombination davon usw.) und zu diesem Ziel wechseln, um es zu beschädigen.
Eine Sache, die Sie in Betracht ziehen sollten, ist, jeder Fähigkeit einen "Kraft" - oder "Effektivitäts" -Stat zu geben, der dem Spieler verborgen ist und nur intern von Ihrer KI verwendet wird. Sie bestimmen die Werte dieser Statistik selbst, basierend auf Ihrem eigenen Wissen über die Fähigkeiten als Programmierer des Spiels.
Ihre KI würde dann ihre Fähigkeit mit der höchsten Bewertung auswählen und versuchen, diese zu verwenden. Wenn sie dies aus irgendeinem Grund nicht kann, wählen Sie die nächste usw. aus. Wenn Sie entsprechend allgemein genug gebaut sind, können Sie diese beiden Systeme miteinander verbinden, sodass Sie, sobald Sie ein Ziel festgelegt haben, Heuristiken für die besten Arten von Angriffen auf dieses Ziel haben (z. B. einen Angriff gewichten, der MP-Schaden verursacht, als effektiver, wenn das Ziel hat einen hohen MP).
quelle