Asteroids
Zum Verständnis der Aufgabenstellung ist die Lektüre des Artikels in c't 9/08 sehr zu empfehlen. Für alle Fragen rund um den Wettbewerb haben wir die E-Mail-Adresse asteroids@ctmagazin.de eingerichtet. Bevor Sie sich mit einem Problem an uns wenden, möchten wir Sie bitten, das eigens eingerichtete Diskussionsforum zu nutzen. Vielleicht hat ja ein anderer Teilnehmer das Problem bereits gelöst oder kann schneller helfen als wir. Gerne dürfen Sie sich im Forum auch über Ihre aktuellen Highscores, Portierungen in andere Programmiersprachen und dergleichen austauschen. Wir freuen uns auf eine produktive Zusammenarbeit.
Aufgrund des regen Interesses haben wir ein Wiki eingerichtet, in dem Sie Portierungen des Beispielcodes in andere Programmiersprachen sowie weitere Informationen finden. Das Wiki ist für jedermann beschreibbar, sodass Sie es selbst um Nützliches ergänzen können. Zum Ändern ist eine (von Ihrem heise online-Account unabhängige!) Registrierung erforderlich.
Aufgrund der hohen Zahl an Voranmeldungen gehen wir von so vielen Teilnehmern aus, dass eine Vorrunde nötig wird, die die Teilnehmer auf ihren eigenen Systemen austragen. Zu diesem Zwecke steht ab sofort eine neue Version von MAME bereit, die das Spiel genau 18.000 Frames (5 Minuten) lang laufen lässt und eine Aufzeichnung von der Partie anfertigt. Die Wettbewerbsbeiträge müssen zusammen mit einer solchen Aufzeichnung eingereicht werden.
Wir werden dann nur die Programme mit den besten 50 Scores unter den im Artikel beschriebenen Bedingungen in der Redaktion laufen lassen und den Wettkampf in fünf Runden austragen. 1. Runde: Die 50 Besten der Vorrunde. 2. Runde: Die 25 Besten treten erneut an. 3. Runde: Die 12 Besten. 4. Runde: Die 6 Besten. 5. Runde: Die 3 Besten. Entgegen der Ankündigung im Artikel beträgt die Laufzeit jeder Runde nur 5 Minuten.
Bitte reichen Sie Ihre Beiträge nicht wie im ursprünglichen Artikel beschrieben per E-Mail ein, sondern per Upload. Sie erhalten an die Adresse, über die Sie die benötigten ROMs bestellt haben, eine Mail mit einer URL, über die Sie Ihren Beitrag zusammen mit der Spielaufzeichnung hochladen können. Einsendeschluss ist der 30. Juni.
Asteroids läuft für diesen Wettbewerb auf MAME, dem Multiple Arcade Machine Emulator, den wir zu diesem Zwecke um eine Netzwerkschnittstelle erweitert haben. Die Windows-Version basiert auf der MAME-Version 0.123, die Versionen für Linux und Mac OS X auf SDLMAME 0.123.
Wir stellen lauffähige und auf das Nötige abgespeckte Versionen für alle drei Betriebssysteme bereit, außerdem die Quelltexte mit unseren Änderungen. Die Quelltexte benötigen Sie nur, wenn Sie MAME selbst übersetzen wollen, was normalerweise nicht nötig sein sollte.
Nicht in MAME enthalten ist die Asteroids-Software, die im Original-Automaten in ROMs gespeichert ist. Die ROM-Images sind urheberrechtlich geschützt und dürfen nicht im Internet verbreitet werden. Die Firma Atari hat uns aber freundlicherweise die Erlaubnis erteilt, die Asteroids-ROMs den Teilnehmern des Wettbewerbs zur Verfügung zu stellen. Wenn Sie mitmachen wollen, schreiben Sie bitte eine E-Mail an asteroids@ctmagazin.de. Wir senden Ihnen dann die 8 KByte große Zip-Datei mit den ROM-Images zu.
Um ein Programm (Client) gegen MAME antreten zu lassen, starten Sie zuerst MAME, dann den Client. Anschließend starten Sie ein Spiel, indem Sie in MAME die Taste 1 drücken. Natürlich können Sie auch selbst Asteroids spielen, indem Sie nur MAME starten. Die vorkonfigurierte Tastenbelegung entspricht so weit wie möglich der Anordnung der Tasten auf dem Original-Automaten, sodass man seine Handhaltung nicht umzustellen braucht, wenn man nach Emulator-Training einmal die Gelegenheit hat, das Original zu spielen:
| Taste | Funktion |
|---|---|
| Q | Links |
| W | Rechts |
| I | Schub |
| O | Feuer |
| Leertaste | Hyperspace |
Die Taste P hält die Simulation an. Mit der Tab-Taste erreichen Sie das Konfigurationsmenü von MAME, wo Sie die Tastenbelegung und diverse andere Dinge umstellen können. Alles Weitere zu MAME finden Sie auf der Homepage des Projekts.
Die Vorrunden-Version von MAME ist dieselbe, die auf dem von der c't-Redaktion betriebenen Asteroids-Server im Internet läuft. Sie startet das Spiel automatisch, zeichnet einen Mittschnitt der Partie auf und bricht sie nach exakt 18.000 Frames ab.
Entpacken Sie die Datei mame-windows-bin.zip oder für die Vorrunde die Datei
mame-windows-bin-recording.zip in einem Verzeichnis Ihrer
Wahl. In das darin befindliche Unterverzeichnis roms
kopieren
Sie die Datei asteroid.zip, die Sie per E-Mail von uns erhalten
haben. Öffnen Sie eine Eingabeaufforderung, navigieren Sie ins
MAME-Verzeichnis und starten Sie den Emulator mit dem Befehl
mameaster asteroid -window -skip_gameinfo
Beim ersten Start wird die Windows-Firewall fragen, ob sie den Netzwerkverkehr dieses Programms zulassen soll. Wenn Sie von einem anderen Rechner aus auf MAME zugreifen wollen, müssen Sie dies erlauben.
Die Vorrunden-Version von MAME schreibt automatisch Aufzeichnungen der übers Netz gespielten Partien ins aktuelle Verzeichnis. Die Spielaufzeichnungen bitte nicht entpacken, sondern als .gz-Dateien belassen.
Entpacken Sie die Datei sample.zip mit dem Beispielprogramm in ein Verzeichnis Ihrer Wahl und navigieren Sie wieder mit einer Kommandozeile in dieses Verzeichnis. Durch Eingabe von
asteroid 127.0.0.1
starten Sie den Client und verbinden ihn mit dem auf dem lokalen Rechner bereits laufenden (!) MAME. Zum Spielen übers Netz ist auf der Kommandozeile statt der 127.0.0.1 die IP-Adresse des Zielrechners anzugeben, auf dem MAME ebenfalls bereits laufen muss.
Das Beispielprogramm wurde entwickelt mit Visual Studio 2008. Die kostenlose Express-Version genügt, um es zu übersetzen. Wenn Sie einen anderen Compiler einsetzen wollen, achten Sie darauf, dass die Präprozessor-Konstante WINDOWS definiert sein muss, sonst hagelt es Fehlermeldungen bei den Socket-Funktionen.
ACHTUNG, FALSCHER VIREN-ALARM: Leider mussten wir kurz vor
Veröffentlichung dieser Seiten feststellen, dass einige
Virenscanner (G Data, F-Prot) das Beispielprogramm asteroid.exe
fälschlicherweise verdächtigen, das Virus
W32/Threat-HLLSI-based!Maximus
zu enthalten. Wir haben die
Hersteller kontaktiert und um Abhilfe gebeten. Sollte bei Ihnen ein
Virenwächter Alarm schlagen, vergewissern Sie sich am besten
durch Lektüre des Quelltextes, dass das Programm nichts
Böses tut und kompilieren Sie es selbst ;-).
Falls Sie MAME selbst kompilieren wollen, finden Sie alles dafür Nötige in der Datei mame-windows-build.zip. Folgen Sie der Anleitung auf mamedev.org.
Die Datei mame-linux-bin.zip enthält ein unter Ubuntu 7.10 (32 Bit) kompiliertes Binary des Emulators, die Datei mame-linux-bin-recording.zip die Vorrunden-Version mit automatischer Spielaufzeichnung. Entpacken Sie die Zip-Datei in ein Verzeichnis Ihrer Wahl, kopieren Sie die per E-Mail erhaltene Datei asteroid.zip ins Unterverzeichnis roms/ (nicht entpacken!) und starten Sie den Emulator mit
./mameaster asteroid -window -skip_gameinfo
Das Binary benötigt die für x86-32-Systeme kompilierte SDL-Bibliothek. Sollte es sich beim Starten über das Fehlen dieser Bibliothek beschweren, so installieren Sie sie bitte nach. Bei neuen Distributionen im Red-Hat-Umfeld (CentOS, Fedora, RHEL) geht dies mit einem Befehl wie yum install SDL. Debianer sollten nach einem Paket wie libsdl Ausschau halten.
Die Vorrunden-Version von MAME schreibt automatisch Aufzeichnungen der übers Netz gespielten Partien ins aktuelle Verzeichnis. Die Spielaufzeichnungen bitte nicht entpacken, sondern als .gz-Dateien belassen.
Der Beispielcode in sample.zip ist derselbe wie unter Windows. Zum Übersetzen sollte ein einfaches make genügen. Zum Laufenlassen bitte die oben beschriebene Reihenfolge einhalten.
Um die gepatchte Version von SDLMAME selbst zu kompilieren, entpacken Sie die Datei mame-linmac-build.tgz und rufen Sie make auf. Sie benötigen dazu die Entwicklerpakete zu SDL und Xinerama (unter Ubuntu libsdl1.2-dev und libxinerama-dev).
Die Datei mame-macos-bin.dmg (Vorrunden-Version: mame-macos-bin-recording.dmg) lässt sich unter Mac OS X durch einen Doppelklick öffnen und enthält ein Icon zum Start des Emulators. Die per E-Mail erhaltene Datei asteroid.zip können Sie auf den Desktop oder in Ihr Home-Verzeichnis legen, wo sie der Emulator automatisch findet.
Die Vorrunden-Version des Emulators legt auf dem Desktop einen Ordner namens Asteroids-Aufzeichnungen an und speichert in diesem die Aufzeichnungen der gespielten Partien. Die Spielaufzeichnungen bitte nicht entpacken, sondern als .gz-Dateien belassen.
Der Beispielcode in sample.zip ist derselbe wie unter Windows. Zum Übersetzen sollte ein einfaches make genügen. Zum Laufenlassen bitte die beschriebene Reihenfolge einhalten.
Sollten Sie die gepatchte SDLMAME-Verion selbst kompilieren wollen, so entpacken Sie die Datei mame-linmac-build.tgz in einem Verzeichnis Ihrer Wahl (für die Vorrunden-Version zusätzlich mame-linmac-recording-patch.zip) und starten make. Die XCode-Umgebung von der Mac-OS-X-DVD muss dazu installiert sein. Des weiteren benötigen Sie die SDL-Bibliothek, die es auf der Homepage des Projekts zum Download gibt. Wer mit den Macports arbeitet, kann sich die SDL-Bibliothek stattdessen mit dem Befehl
port install libsdl
installieren.
Der Beispielcode ist nach Möglichkeit so organisiert, dass das Wichtige oben steht und die technischen Details der Infrastruktur weiter unten folgen. Wenn Sie sich nur mit der Strategie beschäftigen wollen, brauchen Sie in player.cpp nur die Funktion Player::Run() zu bearbeiten. Sie schickt in einer Endlosschleife via SendPacket() ein Paket mit Tastendrücken an den Server, empfängt per ReceivePacket() eines mit dem aktualisierten Bildschirminhalt, interpretiert diesen und drückt dann Tasten, die in der nächsten Runde wieder an den Server geschickt werden.
Die Funktion Player::InterpretScreen() interpretiert den Inhalt des
Vektor-RAM und liefert die in player.h definierte Datenstruktur
GameStatus zurück, die die Koordinaten aller erkannten Objekte in
übersichtlicher Form enthält. Zum Verständnis dieser
Funktion ist die Lektüre des Kastens Die Sprache des Vektorgenerators
im
Artikel hilfreich, zusammen mit dem Beispiellisting.
Wir weisen noch einmal darauf hin, dass der Beispielcode nur als Starthilfe gedacht ist und keinen Anspruch auf Korrektheit erhebt. Programmieren Sie also gerne nach Herzenslust alles selbst oder bedienen Sie sich, so viel Sie mögen!
Die Kommunikation zwischen dem spielenden Programm (Client) und dem Emulator, der das Spiel simuliert (Server) erfolgt per UDP. Der Server lauscht auf Port 1979 auf eintreffende UDP-Pakete eines bestimmten Formats. Wenn er ein gültiges Paket empfangen hat, merkt er sich den Absender und sendet er ab diesem Zeitpunkt alle Bildschirminhalte dorthin.
Das Paket ist in player.h in der Klasse KeysPacket deklariert und besteht aus acht Bytes, von denen die ersten sechs die Signatur "ctmame" enthalten müssen. Das siebte Byte enthält in den unteren fünf Bit die zu drückenden Tasten:
| Bit | Taste |
|---|---|
| 0 | Hyperspace |
| 1 | Feuer |
| 2 | Schub |
| 3 | Rechts |
| 4 | Links |
Die übrigen Bits werden ignoriert; die Beispielimplementierung setzt sie auf 010.
Das achte Byte (Ping-Byte
) kann der Client nach Belieben
verwenden. Es ist dafür gedacht, eine eventuelle Verzögerung
durch das Netzwerk zu messen. Der Server schickt mit jedem Frame das
letzte empfangene Ping-Byte zurück. Die Beispielimplementierung
inkrementiert das Ping-Byte bei jedem geschickten Päckchen. So
kann man messen, um wie viele Frames die empfangenen Bildschirminhalte
hinter den gesendeten Tastendrücken hinterherhinken.
Der Server schickt jeden Bildschirminhalt als 1026 Byte großes Paket. Die ersten 1024 Byte enthalten die gerade aktuelle Hälfte des Vektor-RAM. Eine detaillierte Beschreibung des Formats steht im Artikel.
Das 1025. Byte wird vom Server bei jedem Frame inkrementiert und kann vom Client benutzt werden, um Paketverluste zu bemerken und eventuell in falscher Reihenfolge eingegangene Pakete zu sortieren. Im 1026. Byte schickt der Server das jeweils letzte vom Client empfangene Ping-Byte zurück.
Das Paketformat ist in player.h in der Klasse FramePacket deklariert.
Der UDP-Port 1979 liegt im Bereich der von der IANA (Internet Assigned Numbers Authority) verwalteten registrierten Ports und ist bereits für eine andere Anwendung vergeben:
unisql-java 1979/tcp UniSQL Java unisql-java 1979/udp UniSQL Java # Keith Yarbrough
Wir wurden von einem Mitarbeiter der IETF (Internet Engineering Task Force) auf diesen
Umstand hingewiesen. Es ist in der Tat kein guter Stil, neue
Netzwerkanwendungen auf bereits registrierten Ports laufen zu lassen.
Da allerdings wohl kaum jemand Asteroids über das große,
weite Internet spielen wird, sondern MAME in der Regel auf localhost
oder in privaten Netzen laufen wird, lassen wir die Implementierung
so, wie sie ist. Sollten Sie UniSQL Java
betreiben, so wissen
Sie nun, warum MAME – oder UniSQL Java – nicht richtig
funktioniert. Für eventuelle Unannehmlichkeiten bitten wir um
Entschuldigung.