Archive for the ‘Programmierung’ Category

Roboduel Trading Card Game

Januar 31, 2010

Sammelkartenspiele haben mich schon immer fasziniert. Als langjähriger Magic-Spieler war es schon immer mein Traum, einmal ein eigenes zu entwerfen.

Vor ein paar Jahren wurden wir an der Universität in der Kunst der Assembler-Programmierung unterwiesen und wie es bei Vorlesungen so manchmal ist, schweifen die Gedanken in weite Ferne. Mir kam die Idee, ein Kartenspiel zu machen, bei dem der Kartenstapel jedes Spielers ein Programm darstellt, das im Laufe des Zuges abgearbeitet wird.

Die Programme steuern Roboter, die sich gegenseitig bekriegen, wie beispielsweise beim Roboterfußball.

Eine Roboter-Karte

Ein Roboter hat drei Werte. Links die Box mit dem Blitz ist sein Energievorrat, daneben die Zeit, die ihm pro Runde zur Verfügung steht und rechts seine Panzerung. Sind Energievorrat oder Panzerung erschöpft, so ist das Spiel verloren. Das soll dafür sorgen, dass sich wildes Herumballern nicht lohnt, da die eigene Energie verbraucht ist, bevor man den Gegner erledigt hat.

Wer ich jetzt wundert, welche Zahl A sein soll, dem muss ich zu meiner Schande gestehen, dass Roboduel des Realismus wegen Hexadezimalzahlen verwendet. A ist also 10, B ist 11, …

Jeder Spieler hat also einen Roboter, doch der ist nichts ohne seine Programmierung. Wie programmiert man nun seinen Roboter? Ganz einfach: Es gibt drei Arten von Karten:

  • Befehle, die ein Roboter ausführt (z.B. eine Bewegung)
  • Bedingungen, mittels denen verschiedene Alternativen gewählt werden können
  • Daten, die als Parameter für Befehle und Bedingungen dienen
  • Waffen, um dem Gegner einzuheizen

Ein Befehl

Es gibt zwei Arten von Befehlen, interne und externe. Ein externer Befehl wie der obige ist immer eine Aktion des Roboters. In diesem Fall ein Schritt vorwärts, solange natürlich nichts im Weg steht. Einen Befehl auszuführen benötigt Zeit, die in dem kleinen Fenster unten rechts angegeben ist. Überflüssige Bewegungen sollte man also vermeiden.

Der Sprungbefehl

Im Gegensatz zu externen Befehle brauchen interne keine Zeit, da sie sich sozusagen nur im Gehirn des Roboters abspielen. Der hier abgebildete Befehl ist ein Sprungbefehl, der die nächsten n Befehle überspringt. Er entspricht ein wenig einem GOTO-Befehl, nur, dass er relativ und nicht absolut springt. Allerdings muss natürlich ein Datum folgen.

Ein Datum

Datumskarten gibt es für die Zahlen von 0-F. Als kleinen Bonus enthält die Illustration die Zahl jeweils in Binär- und Hexadezimaldarstellung.

Eine externe Bedingung

Natürlich hilft ein Sprung nicht viel, wenn er immer ausgeführt wird. Dann könnte man sich nämlich einfach die übersprungenen Karten sparen. Deswegen gibt es Bedingungskarten wie die oben abgebildete. Auch hier werden interne und externe Bedingungen unterschieden, wobei die externen wieder Zeit kosten.

Der Text einer Bedingung klingt auf den ersten Blick ein wenig verwunderlich, aber er ist genau das, was man benötigt, um einen bedingten Sprung zu modellieren. Ein Beispiel ist die Kartenfolge „Vor Objekt“, „Sprung“ und „Neun“. Angenommen, unser Roboter befindet sich tatsächlich vor einem Objekt, wird die Bedingung ignoriert und der Sprung um neun Karten wird ausgeführt. Befindet er sich allerdings nicht vor einem Objekt, so wird die Karte „Sprung“ übersprungen, das Datum „Neun“ ignoriert, da es nicht verlangt wurde und das Programm läuft ohne Sprung weiter. Verwirrt? Keine Angst, das ging vielen so.

Eine Waffe

Hat man zu guter Letzt seinen Roboter positioniert, ist es an der Zeit, seinen Gegner in Stücke zu schießen. Dazu benötigt man eine Waffenkarte. Die wird genau wie ein Befehl in den Kartenstapel getan und abgefeuert, sobald sie aufgedeckt wird. Dabei gibt es einen Energieverbrauch (Mitte links) und den beim Gegner verursachten Schaden (Mitte rechts). Die Waffen unterscheiden sich allerdings in der Reichweite, so schießt der Laser z.B. in einer geraden Linie.

Das waren so weit alle Kartentypen, jetzt noch kurz der Spielablauf:

  1. Beide Spieler positionieren ihre Roboter in einer quadratischen Arena, die von Mauern umgeben ist (z.B. mit einem Blatt Karopapier).
  2. Per Münzwurf wird entschieden, wer beginnt.
  3. Die Spieler führen abwechselnd ihre Programme aus, bis die jeweilige Zeit pro Runde für ihren Roboter abgelaufen ist. Reicht die Zeit nicht, den letzten Befehl auszuführen, so wird vorher abgebrochen.
  4. Verloren hat, wessen Roboter keine Energie oder Panzerung mehr hat. Außerdem ist das Spiel verloren, wenn der Speicher überläuft (man hat alle Karten aufgedeckt und keine weiteren Befehle mehr).
  5. Eine Endlosschleife bedeutet unentschieden. Das ist allerdings nicht so ohne Weiteres herauszufinden.

Klingt spannend? Dann empfehle ich, sich einen leidensfähigen Freund zu schnappen und das ganze auszuprobieren. Mehr als ein halbes Dutzend Partien Roboduel wurden bisher nämlich noch nicht gespielt. Der Grund dafür ist einfach: Menschen sind keine Computer. Ist das Spiel begonnen, so ist nämlich bereits entschieden und es liegt nun an den Spielern, ihre Algorithmen auszuführen: Bis zum bitteren Ende. Und obwohl ein Rechenknecht so etwas ohne Anstand in Sekundenbruchteilen erledigt, ist das für ein menschliches Gehirn nicht sonderlich spaßig.

Was allerdings Spaß macht, ist das „Programmieren“ mittels Kartenzusammenstellung. Wer sich mit dem Assemblerlernen ein wenig schwertut, kann es ja mal mit Roboduel versuchen. Nach ein paar Partien hat man auf jeden Fall verstanden, wie so ein Assemblerprogramm funktioniert. Roboduel gibt er hier als druckfertiges PDF.

Tja, leider leider hat es mit Roboduel nicht so ganz geklappt, aber nichtsdestotrotz hat das Design und die grafische Gestaltung jede Menge Spaß gemacht. Aber es war weder das erste selbstgemachte Kartenspiel, noch soll es das letzte bleiben. doch dazu ein andermal mehr…

Ein Datum

Advertisements

ParGM

Januar 10, 2010

ParGM steht für Paralleler Gittermanager und ist ein Projekt, an dem ich im Rahmen meines Studiums mitarbeite. Leute, die eine Abneigung zu Mathematik haben, sollten jetzt besser nicht weiterlesen!

ParGM wird zur numerischen Lösung partieller Differentialgleichungen verwendet und dient hierbei als Gitter

Ein Gitter

Ein Gitter - allerdings keines von ParGM

Aus Programmierersicht interessant ist die Umsetzung in C++, für die sogenanntes Template Metaprogramming verwendet wird.Template Metaprogramming ist eine Technik für statischen Polymorphismus, bei dem zur Compile-Zeit Parameter übergeben werden. Das minimiert den Overhead zur Laufzeit und spart so Performance. Im Falle des Gittermanagers wird das hauptsächlich verwendet, um zwischen verschiedenen Fällen zu differenzieren, z.B. ob das verwaltete Gitter eine, zwei oder drei Dimensionen hat. Abhängig davon werden dann z.B. Arraygrößen festgelegt und Varianten von Algorithmen ausgewählt.

In der Praxis hat Template Metaprogramming allerdings noch einen weiteren Effekt und das ist Frustration der Entwickler. Das Denkmuster ist einem von Java verwöhnten Programmierer nicht auf Anhieb einsichtig und auch die Vorzüge moderner IDEs schwinden schnell, wenn Template-Code ins Spiel kommt. An Code-Completion mit Eclipse war nicht mehr zu denken (letztendlich blieb nur noch Syntax-Highlighting und eine sehr simple Variante des Syntaxchecks übrig) und auch unsere Werkzeuge für Code-Coverage und zyklomatische Komplexität lieferten falsche interessante Ergebnisse. Compilerfehler sind auch schon einmal gut 1000 Zeichen lang, weil jeder Template-Parameter im Detail aufgelistet wird.

So, falls es noch einen Leser gibt, der bis jetzt nicht eingeschlafen ist, findet ihr weitere Informationen und den Quelltext unter pargm.org.