Hallo in die Runde.
Auf ZFX selbst habe ich bisher nur wenig gepostet, doch einige dürften mich noch von Developia kennen. Nach einigen Monaten Entwicklungs- und sonstiger Arbeit (Finanzamt besuchen und ähnlicher Kleinkram) habe ich nun auch ein Projekt vorzuweisen: Eine Android-App, die ich auf Googles Play Store anbiete.
Dabei handelt es sich um ein rundenbasiertes Strategiespiel für zwei Personen. Es gibt Ähnlichkeiten zum Spielprinzip von Schach, Mühle, Dame und dergleichen. Beide Spieler sind abwechselnd am Zug, es gibt keine Zufallselemente und keine unbekannten oder versteckten Elemente. Jedem der beiden Spieler sind alle Informationen zur Spielsituation bekannt.
Hier ein nicht mehr ganz aktuelles Bild:
Das Spielprinzip
Jeder Spieler besitzt zu Beginn einige Felder. Die Spielsteine werden Sterne genannt. Diese Sterne haben einen Wert zwischen 1 und 5. Der Spieler kann in seinem Zug den Wert eines seiner Sterne um 1 erhöhen. Steigt der Wert dadurch auf über 5, "explodiert" der Stern. Zurück bleibt ein Stern mit einem um 5 niedrigeren Feldwert. Als Ausgleich dazu werden alle waagrecht und senkrecht benachbarten Felder dem aktuellen Spieler zugesprochen. Leere Felder erhalten einen neuen Stern mit dem Wert 1. Der Wert eigener Nachbar-Felder und ehemals gegnerischer Nachbar-Felder wird um 1 erhöht. Falls der Wert eines solchen Nachbarn dabei ebenfalls auf über 5 steigt, explodiert dieser ebenfalls. Auf diese Weise können Kettenreaktionen große Teile des vom Gegner besetzten Gebiets erobern - teilweise sogar durch "Fünfer-Sterne" des Gegners.
Technisches
Die Implementierung des Spiels war vergleichsweise einfach, da ich das gleiche Spiel schon im MorgenGrauen umgesetzt habe. Außerdem ist die Google-Dokumentation sehr gut.
Interessant und erwähnenswert finde ich allerdings den computergesteuerten Gegenspieler, gegen den man wahlweise antreten kann. Hier habe ich einigen Gehirnschmalz bemühen müssen, bis ich zu einem einigermaßen brauchbaren Ergebnis gekommen bin. Brauchbar bedeutet hierbei, dass die KI sich nicht völlig zufällig verhält, sondern einem gewissen gewinnorientierten Schema folgt.
Zur Auswahl standen zwei beziehungsweise drei Ansätze.
Zunächst habe ich mit einem Tiefen- und MinIMax-Algorithmus herumprobiert. Das Konzept dieser Vorgehensweise ist technisch noch sehr einfach, jedoch bin ich bei dem umgesetzten Spielprinzip darauf angewiesen, tief in den Baum einzusteigen. Mindestens eine Halbzug-Tiefe von 10 setze ich voraus, um bestimmte Konstellationen als gefährlich oder gewinnbringend einzuschätzen.
Der Bewertungsalgorithmus hingegen konnte vergleichsweise einfach sein. Im Prinzip reichte es aus, die Anzahl besetzter Felder und deren Wert zu summieren und gegen die gleiche Berechnung für gegnerische Felder zu setzen. Dies gab eine grobe Richtung an, in die das Spiel sich entwickeln könnte.
Leider stellte sich schnell heraus, dass der Algorithmus bei 10 Halbzügen überaus lange (zu lange) braucht, um eine Reaktion auf den Zug des Spielers auszuspucken. Obwohl ich grundsätzlich Optimierungspotenzial sehe und sah, habe ich mich dann an einem anderen Ansatz probiert.
Der zweite Ansatz war eine Breitensuche mit MinIMax-Algorithmus, also prinzipiell ein ähnliches Vorgehen wie bei der Tiefensuche. Hier konnte ich einige Optimierungen schon im ersten Ansatz umsetzen.
Die Idee war, dass viele Halbzüge nach zwei oder drei Halbzügen zu gleichen Situationen führen. Daher entschied ich mich, diese Situationen (die sich aus der Spielfeldbelegung und dem aktiven Spieler ergibt) nur ein einziges Mal zu bewerten beziehungsweise weiter zu verfolgen.
Dadurch war es möglich, im Vergleich zum unoptimierten Tiefenalgorithmus um einen Faktor X schneller zu sein. (X müsste ich schätzen, vielleicht auf 100 bis 1000.)
Ärgerlicherweise stellte sich heraus, dass trotz dieser Optimierung sehr viel (zu viel) Arbeitsspeicher notwendig wurde, sobald die Anzahl der Zugmöglichkeiten ansteigt. Auch hier bestünde weiteres Optimierungspotenzial, jedoch wollte ich noch eine dritte Möglichkeit austesten.
Während die Breiten- und die Tiefensuche ihre Stärke daraus ziehen, dass sie "in die Zukunft schauen", also zukünftige Spielsituationen berechnen können, können ihre Bewertungsfunktionen vergleichsweise simpel sein. Die Alternative dazu ist, nicht die zukünftigen Situationen zu berechnen, sondern in einem wesentlich komplexeren Bewertungsalgorithmus eine Zeitpunktbetrachtung vorzunehmen.
Dazu habe ich die einzelnen eigenen Felder des Spielbretts kategorisiert und entsprechend sortiert.
Diese Kategorien unterscheiden zwischen Feldern, die mit gegnerischen Feldern benachbart sind, und Feldern, die es nicht sind. Unter den Feldern mit Fendkontakt gibt es beispielsweise Eroberer (die stärker sind als die stärksten gegnerischen Nachbarn), unbedingte Eroberer (gleich starke gegnerische Nachbarn mit Maximalwert), potenzielle Eroberer (gleichstark wie der stärkste Gegner, aber nicht mit Maximalstärke) und bedrohte Felder oder Opfer. Manche dieser Kategorien können noch weiter unterteilt werden, zum Beispiel in tatsächlich bedrohte Felder und Felder, die von einem Feld bedroht werden, das seine Bedrohung (durch ein anderes eigenes, bedrohendes Feld) nicht ausspielen kann.
Unter den nicht mit Gegnern in Kontakt stehenden Feldern gibt es solche, die selbst an unbesetzte Felder grenzen (siedlungsfähige-Felder) und solche, die im "Hinterland" sind.
Auf meiner Website habe ich einige Taktiken näher beschrieben, die es sinnvoll erscheinen lassen, Hinterland-Felder weiter zu unterteilen, zum Beispiel in solche, die bedrohte Felder absichern, solche, die aggressive Angriffe ermöglichen und ähnliche.
Erstaunlicherweise funktioniert die auf diese Weise gestaltete KI sehr gut. Sie ist in ihrer aktuellen Implementierung zwar noch recht schwach und macht vorhersehbare Fehler, gewinnt aber regelmäßig noch gegen einen siebenjährigen Testspieler. (Zugegeben, das ist nicht die Zielgruppe, aber wenigstens ist die KI gewinnorientiert.)
Die KI ist sogar so schnell, dass der Bewertungsalgorithmus direkt im GUI-Thread durchgeführt werden kann, anstatt ihn in eigene Threads auszulagern.
Einige weitere Informationen könnt ihr auf meiner Website finden
http://android.sistance.de/explode/ und ich freue mich außerdem über Feedback hier im Forum.
Die App ist über den folgenden Link im Play Store verfügbar:
https://play.google.com/store/apps/deta ... id.explode
Gruß,
Torik