creativ'08 Logo

Details zur Teilnahme am Programmierwettbewerb 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.

Neu: Wiki

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.

Ergänzung der Teilnahmebedingungen

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.

Die Software-Umgebung

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:

TasteFunktion
QLinks
WRechts
ISchub
OFeuer
LeertasteHyperspace

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.

Windows

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.

Linux

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).

Mac OS X

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.

Das Beispielprogramm

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!

Das Netzwerkprotokoll

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.

Paketformat Client -> Server

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:

BitTaste
0Hyperspace
1Feuer
2Schub
3Rechts
4Links

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.

Paketformat Server -> Client

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.

Hinweis zur Nutzung des UDP-Ports 1979

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.