Sommer, Python und Hearthstone

Der Sommer neigt sich nun dem Ende zu, und ich bin mitten in meinen Semesterferien. Einige Wochen Urlaub habe ich bereits hinter mir; inzwischen packt mich auch wieder die Motivation für meine privaten Projekte.

Zum ersten Mal bin ich nun ein regelmäßiger „Contributor“ bei einem richtigen Open-Source-Projekt geworden: Fireplace! Für mich ist das mein erstes größeres Python-Projekt (was ich von Python halte - dazu nachher mehr) und gleichzeitig auch eine Möglichkeit, Teil eines Teams aus begeisterten Hearthstone-Fans zu sein. Zwar habe ich bereits vorher viel mit anderen Entwicklern Erweiterungen für ein Spiel über das Internet gebaut, aber diesmal geht es um ein bekannteres und aktuelleres Spiel.

Hearthstone

Hearthstone ist ein virtuelles Fantasy-Kartenspiel für zwei Spieler von Blizzard Entertainment. Das Spielprinzip erscheint verblüffend einfach: Jeder Spieler ist abwechselnd dran und bringt ein selbst-zusammengestelltes Deck aus 30 Karten mit. Zu Beginn der Runden erhält der aktuelle Spieler eine Karte aus seinem Deck und 1-10 "Manakristalle" - die Hauptressource des Spiels. Ziel ist es nun, die Lebenspunkte des gegnerischen Spielers von 30 auf 0 zu bringen. Dazu spielt man Karten mit "Manakosten aus" die beispielsweise dem anderen Spieler schaden, dem eigenen Spieler helfen, und sogenannte Kreaturen, die auf der eigenen Seite Spielfeld platziert werden. Diese Kreaturen können nun auch den Gegner oder seine Kreaturen angreifen.

Der interessante Teil des Spiels (und der Grund, weshalb das ein virtuells Spiel ist) sind nun die besonderen Texte auf den meisten Karten. Mal nimmt entweder zufällig der Gegenspieler oder eine seine Kreaturen Schaden sobald man eine eigene Kreatur spielt, man erhält beim Spielen der Karte eine völlig zufällige Kreature, oder zum Ende jeder Runde erhalten die Spieler und alle Kreaturen auf dem Spielfeld zwei Schaden.

Komplex wird das dadurch, dass es mehrere hundert verschiedene Karten gibt, und die Interaktionen zwischen den Karten schnell sehr komplex werden und zu außergewöhnlichen Ergebnissen führen können. Selbst erfahrene und professionelle Spieler werden manchmal überrascht, wenn die Dinge nicht so laufen wie sie sich es vorgestellt haben.

Aus diesem Grund hat sich das Team hinter hearthsim.info zusammengetan: sie testen und protokollieren diverse Interaktionen, erstellen daraus Regeln und Modelle um das Verhalten zu beschreiben und sind generell die, die wohl die seltsamsten Dinge mit dem Spiel machen. Daraus wurden dann diverse Simulatoren für das Spiel und eben auch Fireplace, bei dem ich nun mitmache. Ein Simulator nimmt als Eingabe den Zustand des Spiels und Aktionen der Spieler und soll daraus dann das möglichst richtige Ergebnis liefern. Es macht mir vor einfach Spaß neue Testfälle für Fireplace zu schreiben, indem ich mir vorstelle wie die Situation im Spiel ablaufen würde. Inzwischen habe ich auch einige Änderungen in den Tiefen des Simulators zu verantworten, aber die Testläufe des Simulators mit den entsprechenden Protokollen erfüllen mich bis heute immer wieder mit Freude.

Python

Fireplace ist nun also in Python gebaut. Viel habe ich schon von überzeugten Entwicklern über diese mysteriöse Sprache ohne geschweifte Klammern gehört, und nun baue ich selbst etwas damit.

Kurzer Einschub: Ich bin zum Zeitpunkt dieses Eintrags völliger Python-Neuling und habe nicht einmal zwei Monate Erfahrung damit. Dennoch bin ich schon mit vielen anderen Sprachen in Kontakt gekommen und würde mich als einen ziemlich fortgeschrittenen Entwickler sehen. Das hier sind meine persönlichen Erfahrungen bis zu diesem Zeitpunkt, und vielleicht habe ich nächste Woche bereits eine andere Meinung über Manches.

Also, Python nun. Als erste Besonderheit sticht für mich als eigentlich geschweifte-Klammern-orientiertem Entwickler (PHP, Java, Lua, Javascript) natürlich die Einrückung von Blöcken als Kennzeichnung des Programflusses aus. Wo andere Communites über die genaue Positionerung der Klammern streiten, gibt sich Python eigentlich nur mit dem klassischen Leerzeichen-versus-Tabs-Problem ab (wobei die das schon quasi standardisiert haben). Was anfangs ungewohnt erscheinen mag, führt schnell zu sehr kompakten und lesbaren Blöcken Code - und damit meine ich nicht „:(){ :|:&};:“.

Ganz im Gegenteil:

for minion in self.controller.field.filter(has_inspire=True):
    if not hasattr(minion.data.scripts, "inspire"):
        raise NotImplementedError("Missing inspire script for %r" % (minion))
    actions = minion.data.scripts.inspire
    if actions:
        ret += self.game.queue_actions(self, actions)
return ret

Ich finde Python-Code damit ziemlich schön: es sind weniger Zeilen nötig, und man kann Blöcke genauso schnell wie in anderen Sprachen erfassen. Eine tolle Sache.

Wo wir gerade bei dem obigen Snippet sind: benannte Parameter sind ein Feature, das eigentlich jede Sprache haben sollte. Was in Javascript umständlich mit den extrem häufigen Parameter-Arrays und dem Mergen mit einem Default-Array gemacht wird ist so schnell und schön lösbar. Zudem bieten sie eine gewisse Flexiblität gegenüber API-Änderungen an den Parametern und erhöhen die Lebarkeit ungemein: card.play(target=wisp) im Vergleich mit card.play(wisp).

Was gibt's noch? Einen brauchbaren Paketmanager (der auch im Gegensatz zu npm keine 20 Sekunden lädt) und ein nützliches Testframework. Schön sind Stringoperationen wie z.B. " hello world!".strip() (hallo PHP!). Etwas kurios finde ich noch die Organisation von Importen (os vs sys), aber das ist ziemlich sicher Gewöhnungssache.

Etwas wurmt mich noch die Tatsache, dass das NetBeans-Plugin für Python etwas featureschwach ist und vor allem die Autovervollständigung und der Sprung zu einer Klassendeklaration selten klappt. Klar, dynamische Sprache und so, aber bei PHP und Javascript klappt das doch meistens auch. Auch bei einer kurzen Recherche konnte ich micht nicht für eine der IDEs erwärmen, aber das kommt sicher auch noch (als nächstes versuche ich mal PyCharm).

Insgesamt ist es jedoch spannend, wieder einmal mit einer neuen Sprache und Laufzeitumgebung in Kontakt zu kommen. Mitte des Jahres hatte ich mal etwas konkretere Berührungspunkte mit Server-/Anwendungsjavascript unter node (das ist noch einmal eine völlig andere Welt zum „normalen“ Javascript in HTML) und bisher bin ich von Python durchaus positiv angetan. Ein besseres Shellskript habe ich auch schon damit gebaut und ich freue mich sehr, dass ich in Zukunft auf eine weitere Sprache zurückgreifen kann.

[Zurückgehen].