-Spieler in Java
Diese Seite gibt Zugriff auf eine erste Implementierung
eines automatischen Spielprogramms für das Spiel Asteroid von
1979, die als Antwort auf den Wettbewerb
creativ '08: Asteroids der Zeitschrift c't
programmiert wurde.
Menü
- Version 0.97 veröffentlicht (Fr 11. Jul 12:10:16 CEST
2008)
Dieser Release dient nur dazu, dem Applet auch unter Windows zu
erlauben, Popups anzuzeigen.
- Version 0.96 veröffentlicht (Do 3. Jul 18:32:54 CEST
2008)
Diese Version fixed ein Problem beim Berechnen der Schuss-Statistik
(erreichbar über das Kontextmenü in der Anzeige),
allerdings werden immer noch Schüsse als Fehlschuss interpretiert,
wenn ein Teil eines zerschossenen Asteroiden gleich getroffen wird,
ohne überhaupt auf dem Schirm zu erscheinen.
Außerdem hat jetzt auch die TimeLine eine Kontextmenü, über das
man gezielt Frames und Zeitpunkte anspringen kann.
- Version 0.95 veröffentlicht (Di 1. Jul 19:59:48 CEST
2008)
Dieser Update dient dazu, das Applet endlich mit nicht mehr zappelnden
Geschwindigkeitsvektoren zu versehen. Es gibt auch ein paar kleine
Statistiken im Kontextmenü des Anzeigefensters.
Außerdem kann man jetzt auch meinen
Wettbewerbsbeitrag herunterladen, der aber nur gut 100.000 Punkte schafft.
- Abwesenheitswarnung (Mi 21. Mai 21:58:16 CEST 2008)
Ich werde bis Sonntag auf Radtour und daher nicht erreichbar sein.
- Version 0.78 veröffentlicht (Mi 21. Mai 21:52:32 CEST
2008)
Bugfix im Menschenklient: jetzt wird die letzte Taste nicht mehr in das
nächste Spiel mitgenommen.
- Version 0.77 veröffentlicht (Mo 19. Mai 22:25:08 CEST
2008)
Haralds Wunsch ist mein Befehl:
Möglichkeit addiert, auch als Mensch mit dem Online-MAME zu
spielen.
Dafür wurde die
Klasse Communication
ein wenig erweitert, um auch die Spezialantworten des Online-MAMEs zu
verstehen, und je nachdem zwischen verschiedenen internen Statii zu
wechseln.
Menschliche Spieler werden mit einem Smiley ☻ (Unicode #263B)
versehen, um sie von den Bots zu unterscheiden.
- Version 0.73 veröffentlicht (Mi 14. Mai 09:39:12 CEST
2008)
Betrifft nur das Applet:
Fixed einen Bug, der dafür sorgte, dass nach dem Laden einer neuen
Datei die Geschwindigkeiten-Checkbox nicht synchron mit dem
tatsächlichen Zustand war.
- Version 0.72 veröffentlicht (Di 13. Mai 21:38:38 CEST
2008)
Betrifft nur das Applet:
Addiert die Möglichkeit eines automatischen Starts, wenn ein
Dump geladen wurde.
- Version 0.70 veröffentlicht (Mo 12. Mai 18:50:53 CEST
2008)
Diese Version beinhaltet in der Hauptsache diverse Erweiterungen für
das Applet, das nun auch Explosionen von Asteroiden, Ufos und
insbesondere Schiffen anzeigt (Dank an damics und
DLKing für ihre wertvolle Unterstützung) und sogar die
Beschleunigung darstellt und damit ziemlich dicht an die
Originaldarstellung herankommt. Sie stellt auch einen größeren Bereich
als die magischen 1024x768 Pixel dar, was ebenfalls dem Original
entspricht (sonst wäre der Score oben abgeschnitten).
- Version 0.66 veröffentlicht(Mi 7. Mai 16:03:19 CEST
2008)
Diese Version implementiert einen Workaround für das nervige
Problem des Applets im Zusammenhang mit JavaScript in Firefox,
der das Problem bei mir zumindest löst, sodass ich zum Testen
nicht mehr auf den ollen Internet Explorer angewiesen bin.
Außerdem malt er das Bild auf Wunsch von Harald jetzt etwas
"klassischer" mit überstrahlenden Schüssen.
- Version 0.65 veröffentlicht(Mi 7. Mai 13:23:13 CEST
2008)
Dieser Release dient der Angleichung der Zeitbasen zwischen den
verschiedenen Dump-Files. Bei meinen wurden bisher echte
Zeitstempel verwendet, wodurch ein Frame nicht genau
durchschnittlich 1/60 Sekunde
dauert, abhängig vermutlich von der Tagesform des MAMEs oder
der Mondphase. In der neuen Version wird überall davon ausgegangen,
dass 60 Frames einer Sekunde entsprechen.
Um den eigenen Stand leichter überprüfen zu können, gibt es jetzt auch
die
Klasse TimedScorePrinter,
die dem Communication-Objekt als FrameListener mitgegeben werden kann
und nach einer wählbaren Anzahl von Frames nach Erscheinen des Schiffs
(analog zu den c't-Dumps) den aktuellen Score ausgibt.
Außerdem wird noch ein Problem mit einem Offset der Marker um 1 gefixt.
- Version 0.64 veröffentlicht(Mi 7. Mai 08:46:23 CEST
2008)
Bugfix-Release: diese Version versteht auch das neue c't-Format, wenn
kein Name eingetragen ist. Ein Danke an
DLKing, der
mir diesen Bug verraten hat.
- Version 0.63 veröffentlicht (Di 6. Mai 20:37:52 CEST
2008)
Diese Version ändert lediglich das Design des Analysefensters, um den
Platz sinnvoller zu nuzten.
- Version 0.62 veröffentlicht (Di 6. Mai 19:54:27 CEST
2008)
Harald hat einfach eine neue Version des Dateiformats erfunden, deshalb
waren ein paar Anpassungen notwendig, um auch diese Version einlesen zu
können.
- Version 0.61 veröffentlicht (Di 6. Mai 10:47:45 CEST
2008)
Neben einem kleinen Bugfix (ein fehlendes break in FrameInfo,
auf das mich Sebastian aka mafu freundlicherweise hinwies) gibt es hauptsächlich
Änderungen, damit der Analysator auch die Dumpfiles von Harald einlesen
kann und als Applet läuft. Dazu gehört
implizit ein Rückport auf Java 1.5, weil das die Chance erhöht, dass
das Applet auch auf etwas exotischeren Systemen läuft. Die Versionsnummernsprung ist aber
hauptsächlich dem Umstand geschuldet, dass ich mich inzwischen auch der
eigentlichen Aufgabe des Wettbewerbs widme, und die Versionsnummern
auch intern für mich hochzähle.
- Version 0.53 veröffentlicht (So 27. Apr 20:41:29 CEST
2008)
Mittlerweile konnte ich mal testen, was passiert, wenn ein Score
überläuft, und natürlich funktionierte meine
ScoreFixer-Klasse,
die das abfangen sollte, überhaupt nicht.
Das ist in dieser Version gefixt.
Es gibt noch einige kleinere Anpassungen, z. B. werden jetzt
Fließkommakoordinaten für Geschwindigkeiten verwendet. Und es gibt eine
Zeitanzeige im Display, die verrät, wie lange das aktuelle Spiel gerade
läuft, damit man in etwa abschätzen kann, wieviel man in fünf Minuten
so zusammenbekommt.
- Version 0.52 veröffentlicht (Mi 23. Apr 12:06:35 CEST 2008)
Diese Version dient als erneuter Bugfix für den notorischen
HallOfFameFiller,
der nicht mal mein eigenes Kürzel eintragen konnte.
Außerdem habe ich jetzt angefangen, meinen Player vom Rest des Projekts
zu entkoppeln, sodass ich alles veröffentlichen kann, ohne meinen
eigenen Playeransatz herausgeben zu müssen. Das beschert den neuen
Schalter -p (s. u.).
- Tutorial: Laden des Projekts in Eclipse (Di
22. Apr 14:29:02 CEST 2008)
Da ich dieses Projekt als Einstiegshilfe für Anfänger begreife und auch
schon entsprechende Anfragen erhalten habe, habe ich mal versucht,
das Projekt in Eclipse (das ich selbst nicht verwende)
einzubinden. Meinen Weg habe ich auf einer eigenen
Seite beschrieben.
- Version 0.51 veröffentlicht (Di 22. Apr 11:24:10 CEST 2008)
Sie unterscheidet sich von der 0.50 lediglich dadurch, dass ich auch
die Datei asteroids.properties beipacke, die vom
Ant-Makefile asteroids.xml
eingebunden wird. Die darin enthaltene Zeile beschreibt allerdings mein
System und muss bei Euch entsprechend angepasst werden.
- Version 0.50 veröffentlicht (Mo 21. Apr 21:32:48 CEST 2008)
Diese Version ist vermutlich, bis auf eventuelle Bugfixes, erstmal
die letzte, die ich in nächster Zeit veröffentliche werde, da ich
inzwischen genug Infrastruktur geschaffen habe, um endlich mal selbst
einen Spieler zu basteln.
- Der Bug mit den bisweilen fehlerhaften
Einträgen in der Hall of Fame ist hiermit behoben.
- Die Berechnung der Ping-Zeiten funktioniert auch erst jetzt
brauchbar, weil vorher das ping nicht hochgezählt wurde.
- Diese Version ermöglicht es, die von MAME erhaltenen
und dorthin gesendeten Daten in eine Datei zu schreiben.
- Und natürlich gibt es ein Tool, um diese Datei danach in
Ruhe zu analysieren.
- Für die Icons im Analysator muss die mitgelieferte Datei
lib/jlfgr-1_0.jar mit eingebunden werden. Bitte Lizenz
beachten. Sie
stammt aus
dem Look&Feel Graphics Repository von Sun.
- Version 0.31 veröffentlicht (Sa 19. Apr 13:18:34 CEST 2008)
Beseitigt einen Bug mit dem Bridge-Modus.
- Version 0.30 veröffentlicht (Fr 18. Apr 14:35:37 CEST 2008)
Eigentlich wollte ich gar nichts mehr veröffentlichen, aber Clawq hat
einen Bug entdeckt (der hier unerklärlicherweise nicht auftritt), und
daher habe ich nicht nur einen Fix dafür, sondern es gibt auch gleich noch eine
Reihe Erweiterungen in der "Infrastruktur". Für Leute, die
schon eine ältere Version benutzt haben, ändert sich ein bisschen
was, was ich in den folgenden Punkten noch erwähne.
- Diese Version fixt zunächst mal einen Bug, der bei mir allerdings
erstaunlicherweise nicht auftrat. Siehe
dazu den
Post von Clawg und meine
Antwort dazu.
-
Da MAME nur ein Datagramm pro Frame verarbeiteit, habe ich das
Senden der Tastendrücke so umgebaut, dass dieses nur noch passiert,
wenn ein Frame empfangen wurde. Die bisherige sendKey()-Methode ist
nicht mehr vorhanden, stattdessen gibt es pushKey()- und setKey()-Methoden.
-
Neben Explosionen werden jetzt auch Texte aus dem Schirm
ausgelesen. Daher können jetzt verschiedene Statii unterschieden
werden (im Spiel, nicht im Spiel, Spielende-Schirm ...).
-
Der letzte Punkt ermöglicht automatischen Spielstart (dafür ist
allerdings ein gepatchtes Mame nötig, der Patch ist über das Wiki verfügbar) und auch
ein automatisches Eintragen in die "Hall of Fame".
- Version 0.15 veröffentlicht (Di 15. Apr 18:59:40 CEST 2008)
Diese Version addiert in der Hauptsache eine Geschwindigkeitsanzeige.
- Version 0.10 veröffentlicht (Di 15. Apr 14:20:02 CEST 2008)
Die erste Version orientiert sich am
mitgelieferten Beispiel von Harald Bögeholz. Sie erlaubt
zusätzlich die Anzeige des ausgelesenen Bildes.
Bibliothek
- Version 0.97
(763,756 Bytes /
Thursday, 14-Jun-2018 14:56:16 CEST)
- Version 0.96
(764,021 Bytes /
Thursday, 14-Jun-2018 14:56:16 CEST)
- Version 0.95
(756,965 Bytes /
Thursday, 14-Jun-2018 14:56:16 CEST)
- Version 0.78
(703,288 Bytes /
Thursday, 14-Jun-2018 14:56:15 CEST)
- Version 0.77
(703,343 Bytes /
Thursday, 14-Jun-2018 14:56:15 CEST)
- Version 0.73
(542,132 Bytes /
Thursday, 14-Jun-2018 14:56:15 CEST)
- Version 0.72
(540,346 Bytes /
Thursday, 14-Jun-2018 14:56:15 CEST)
- Version 0.70
(539,507 Bytes /
Thursday, 14-Jun-2018 14:56:15 CEST)
- Version 0.66
(381,603 Bytes /
Thursday, 14-Jun-2018 14:56:14 CEST)
- Version 0.65
(380,358 Bytes /
Thursday, 14-Jun-2018 14:56:14 CEST)
- Version 0.64
(378,207 Bytes /
Thursday, 14-Jun-2018 14:56:14 CEST)
- Version 0.63
(378,171 Bytes /
Thursday, 14-Jun-2018 14:56:14 CEST)
- Version 0.62
(378,130 Bytes /
Thursday, 14-Jun-2018 14:56:14 CEST)
- Version 0.61
(376,630 Bytes /
Thursday, 14-Jun-2018 14:56:14 CEST)
- Version 0.53
(241,395 Bytes /
Thursday, 14-Jun-2018 14:56:13 CEST)
- Version 0.52
(233,773 Bytes /
Thursday, 14-Jun-2018 14:56:13 CEST)
- Version 0.51
(230,206 Bytes /
Thursday, 14-Jun-2018 14:56:13 CEST)
- Version 0.50
(230,030 Bytes /
Thursday, 14-Jun-2018 14:56:13 CEST)
- Version 0.31
(90,116 Bytes /
Thursday, 14-Jun-2018 14:56:13 CEST)
- Version 0.30
(90,087 Bytes /
Thursday, 14-Jun-2018 14:56:13 CEST)
- Version 0.15
(55,461 Bytes /
Thursday, 14-Jun-2018 14:56:13 CEST)
- Version 0.10
(42,758 Bytes /
Thursday, 14-Jun-2018 14:56:13 CEST)
Wettbewerbsbeitrag
Erklärungen zum Aufbau (bisher noch nicht viel)
Diese Veröffentlichung dient dazu, Java-Anfängern schon
mal eine Basis in die Hand zu geben, um sich nicht um die Details
der UDP-Kommunikation und die Bitschiebereien beim Auslesen
des Vektorspeichers kümmern zu müssen. Mittlerweile basiert auch das in
der der Games-Seite
verwendete Applet auf diesem Code (und ist natürlich in den Quellen
enthalten).
Bitte versucht, mit den hier angegebenen Dokumenten (für das eigentliche
Programm) und frei verfügbaren Hilfen (für Java im Allgemeinen)
klarzukommen, da ich nur begrenzt Zeit habe, Eure E-Mails zu beantworten.
Ansonsten gibt es ja auch das Forum oder das
Wiki.
Es gibt eine javadoc-Dokumentation der jeweils
aktuellsten Version.
Basis ist hier bei mir zuhause bis inklusive Version 0.52 JDK 1.6,
danach JDK 1.5 ohne irgendwelche Besonderheiten.
Die Implementierung ist effektiv genug, dass sie inklusive Anzeige
hier bei unter 5% Rechnerauslastung dümpelt (AMD Athlon(tm) 64 X2 Dual
Core Processor 4200+ unter Linux), also bleibt noch genug Raum für
Optimierungen.
Die Klasse
de.caff.asteroid.Communication dient der Kommunikation
mit dem MAME-Prozess. Sie läuft in einem eigenen Thread. Bei
eingehenden Datagrammen konvertiert sie diese in ein
de.caff.asteroid.FrameInfo,
das schon Objekte wie
Asteroid
und SpaceShip
kennt.
Als Beispielimplementierung dient
SampleAsteroidPlayer,
der im Großen und Ganzen dem Beispiel von Harald entspricht.
Im Gegensatz zu Haralds C++-Version verwendet diese Version Threads,
in der vorliegenden Version allerdings nur für die Kommunikation,
die in einem Extra-Thread läuft (und damit unabhängig vom
Zeichnen ist). Sinnvollerweise sollte auch die KI in einem eigenen
Thread laufen, aber im Moment klinkt sie sich in den
Kommunikations-Thread ein, da sie über das
FrameListener
an die Kommunikationsklasse anhängt.
Generell muss das Programm immer nach MAME gestartet werden.
java -jar asteroid.jar [hostname[:port]] [-d] [-b port] [-s file]
java -jar asteroid.jar -P [hostname[:port]]
hostname[:port] |
Angabe des Hosts, auf dem MAME läuft.
Port von MAME ist natürlich immer 1979 und kann daher
entfallen. Momentan gibt es die Angabe nur, damit ich den
Bridge-Modus testen konnte. Ohne Angabe des Hostnamens
wird 127.0.0.1 (Localhost) angenommen.
|
-d |
Displaymode.
Öffnet ein Fenster, das die eigene Idee des Vektorspeichers
darstellt.
|
-b port |
Bridgemode.
Reicht die von MAME generierten Datagramme über den
angegebenen lokalen Port weiter und vice versa.
Im Moment kann dies höchstens
dazu verwendet werden, dass auch andere Programme dort
anmelden können, um zum Beispiel bei einem remote laufenden MAME
trotzdem lokal was anzeigen zu können. Natürlich wird die Latenz
dadurch ein wenig erhöht.
Die Idee dahinter ist allerdings, später einmal auf diese Weise
den von Harald vorgeschlagenen 3D-Modus zwischenschleifen zu
können.
Im Bridgemode versucht das Programm natürlich nicht selbst
zu spielen.
|
-s file |
Dump.
Alle erhaltenen und gesendeten Daten werden in die
Datei file geschrieben. Diese Datei kann später mit einem
weiteren Tool (s. u.) ausgelesen und analysiert werden.
|
-p player |
Player festlegen.
Legt den Klassennamen eines PlayerStarters fest,
der einen bestimmten Player installiert.
Es kann entweder der komplette Klassennamen angegeben werden,
oder ein Kürzel, dem wenn nötig noch der Präfix
"de.caff.asteroid." und der Suffix
"PlayerStarter angehängt wird. Momentan sind folgende
Player vorhanden (Kurzform, Groß- und Kleinschreibung ist wichtig):
- rammi.Rammi: gibt's nur bei mir zuhause
- Sample: Haralds Beispielimplementierung
- Stupid: Die Arnold-Version: Gasgeben und schießen
Wird kein Player angegeben, wird versucht, diese in der angegebenen
Reihenfolge zu starten. Da meine Klassen nicht mitgeliefert werden,
gibt es den ersten Player nicht und daher wird dann der
Sample-Player von Harald gestartet.
Im Bridge-Modus wird kein Player gestartet, daher ist dieser Schalter
dort sinnlos.
|
-P [hostname[:port]] |
Erlaubt das Spielen als Mensch.
Defaultmäßig wird das Online-MAME
unter asteroids.heise.de:1979 verwendet, die Tastenbelegung
ist wie
unter Wettbewerbsseite
beschrieben:
Taste | Funktion |
Q | links drehen |
W | rechts drehen |
I | Schub |
O | Feuer |
Leertaste | Hyperspace |
1 | neues Spiel (nicht beim
Online-MAME, sondern nur bei einem modifizierten lokalen) |
ACHTUNG: Falls nicht gegen ein modifiziertes MAME gespielt wird, ist dies im
am Anfang angezeigten Einstellungsdialog auch so anzugeben, sonst
stürzt das MAME ab.
Das mitgelieferte Skript runHumanPlayer.sh
bzw. runHumanPlayer.bat startet ein Spiel mit dem
Online-MAME, setzt aber noch einige sinnvolle Parameter für das
verwendete Java.
|
Ein paar Beispiele:
- java -jar asteroid.jar
sollte sich prinzipiell wie Haralds C++-Programm verhalten.
- java -jar asteroid.jar -d -s ast.dump -p Sample
genauso, aber mit Anzeige, außerdem werden die versendeten
Daten zu späteren Analyse in die Datei ast.dump geschrieben.
Die Angabe des Players ist in Eurer Umgebung redundant.
- java -jar asteroid.jar -b 1962 -d
Startet eine Anzeige im Bridgemodus, die die MAME-Datagramme
an den lokalen Port 1962 weiterleitet.
- java -jar asteroid.jar 127.0.0.1:1962
spielt über die im vorigen Beispiel gestartete Bridge.
Was nützt einem eine Dumpdatei, die man nicht anschauen kann?
Daher ist auch ein Analysetool enthalten, das man auf die folgende Weise
starten kann:
java -mx1800m -cp asteroid.jar de.caff.asteroid.analysis.AnalysisDisplay [-s] dump-datei
Der Java-Schalter -mx1800m sorgt für genug Speicher (1800 MByte)
und muss vielleicht bei Dir angepasst werden (viel mehr gibt 32-Bit-Java
aber nicht her). Der Speicherbedarf hängt natürlich von der Größe der zu
analysierenden Dump-Datei ab. Die können recht groß werden, pro Minute
sind es etwa 3,7 MByte.
Ab Version 0.61 werden auch Dumpfiles in dem von der c't verwendeten
Format verstanden (ab 0.62 auch die 2. Version), und Dumpfiles dürfen auch gepackt sein mit ZIP oder
GZIP, und als kleine Hilfe gegen die Firefox-Appletprobleme kann man auch
eine URL angeben (falls Du über einen Proxy surfst, muss dieser
allerdings noch in der Kommandozeile nach dem java in der Form
-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 angegeben
werden. Ebenfalls ab dieser Version gibt es den Schalter -s, der
ein reduziertes Interface ähnlich dem Applet startet.
Das Ergebnis sieht dann etwa so aus (unreduziert):
Wie man sieht, hat das Fenster verschiedene Bereiche. Ganz unten ist
die Timeline, die den Inhalt der Datei in zeitlicher Reihenfolge
darstellt, blau steht für Frames im Spiel (dunkelblau mit und hellblau
ohne Schiff) und orange für welche dazwischen. An den Übergängen werden
automatisch Marker gesetzt, die sich über die Knopfleiste oben mittig
anspringen lassen. Die zwei schwarzen
Dreiecke mit dem Strich dawischen markieren den aktuellen Frame.
Wie zu erwarten kann man
auch mit der Maus draufklicken oder draggen und die Markierung verschiebt
sich entsprechend. Rollt man über der Timeline oder der grafischen
Anzeige am Mausrad, bewegen sich
die Frames mit jedem Klick vor oder zurück (mit SHIFT von Markierung zu
Markierung).
Den Index des aktuellen Frames sieht man übrigens im Titel.
Ebenfalls hauptsächlich zur Navigation dient der Toolbar oben. Die
Doppelpfeile machen keinen schnellen Rück- oder Vorlauf, sondern
verschieben frame-weise (ich habe nur auf die Schnelle keine passenderen Icons
gefunden). Die Pfeile mit dem Strich dran gehen zum vorigen bzw. nächsten
Marker (also Übergang zwischen Spielphase und Zwischensequenz). Die
Playtaste lässt das Spiel dann automatisch ablaufen, bei mir allerdings
etwas langsamer als das Original, weil die ganze Informationsanzeige dann
doch Zeit frisst. Schließlich kann man mit
der Velocities-Checkbox anschalten, ob Geschwindigkeitspfeile
berechnet und angezeigt werden (die werden dann im Hintergrund berechnet
bzw. entfernt, daher ist die Reaktion nicht instantan, aber doch
verblüffend schnell).
Die Box Buttons direkt drunter enthält die zwischen dem letzten
und diesem Frame gesendeten Buttons. Normalerweise ist das nur ein Paket,
allerdings kann das im Bridge-Modus anders aussehen.
Links in der Box Game Objects gibt es eine Übersicht über den
Frame und die darin enthaltenen Objekte. Diese können selektiert werden,
und die Daten des jeweils selektierten Objekts werden dann im Bereich
Properties of Selected Object in der Mitte rechts angezeigt.
Die Selektion wird auch durch einen magentafarbenen Rahmen
im Frame-Display unten rechts markiert. Umgekehrt kann man dort
auch auf ein Objekt klicken, um es zu selektieren und dadurch seine
Eigenschaften angezeigt zu bekommen.