Der Spielleiter (Server)

Die beiden Computerspieler kommunizieren nicht direkt miteinander, sondern übertragen ihre Nachrichten über einen Mittelmann: den Spielleiter. Dadurch ist zum einen sichergestellt, dass man seinen Gegner nicht mit illegalen Nachrichten belästigen kann, zum anderen sorgt der Spielleiter dafür, dass sich die Kontrahenten an die Spielregeln halten.

Der Spielleiter ist direkt im Wettkampfsystem integriert, so dass alle Turnierspiele regelkonform gespielt werden müssen. Zum Testen des eigenen Computerspielers gibt es eine spezielle Version des Spielleiters, die im Downloadbereich (http://www.software-challenge.de) heruntergeladen werden kann. Diese Download-Version, die in diesem Abschnitt beschrieben wird, besitzt eine grafische Oberfläche, durch die man das Spiel gut verfolgen und sogar als Mensch mitspielen kann.

System vorbereiten und Spielleiter starten

Die einzige Vorraussetzung ist, dass auf dem Rechner mindestens die Laufzeitumgebung für Java 8 installiert ist. Siehe Installation von Java.

Nach der erfolgreichen Installation kann man den Server durch einen Doppelklick auf die Datei software-challenge-gui starten.

Die Programmoberfläche

Die Programmoberfläche besteht aus dem Menü links sowie der Spielfläche in der Mitte.

Spielleiter
Figure 3. Die Spielleiteroberfläche direkt nach dem Programmstart

Auf der linken Seite sind alle möglichen Aktionen aufgelistet.

Zu Beginn ist die Spielfläche leer.

Ein neues Spiel erstellen

Um ein Spiel zu spielen, muss zunächst über das Menü links "Neues Spiel" die folgende Ansicht aufgerufen werden:

Neues Spiel
Figure 4. Dialog für ein neues Spiel

In diesem Fenster werden die Spieler ausgewählt, die an dem Spiel teilnehmen sollen. Für jeden Spieler gibt es folgende Optionen:

  • Name: Hier kann für jeden Spieler ein Name eingegeben werden, der dann im Spiel angezeigt wird.

  • Spielertyp: Es kann zwischen 3 verschiedenen Spielertypen gewählt werden:

    1. Mensch: Ein menschlicher Spieler, der über die Programmoberfläche spielt.

    2. Computerspieler: Ein Computerspieler in Form eines separaten Programms, das beim Starten des Spiels automatisch vom Server gestartet wird.

    3. Manuell gestarteter Client: Ein Computerspieler in Form eines separaten Programms, das manuell durch den Benutzer gestartet werden muss.

  • Wähle ein Programm zum starten (auswählbar für 'Computerspieler'): Bei Spielertyp ‚Computerspieler’ ist eine Programmdatei auszuwählen, deren Name dann hier angezeigt wird.

Nach Eingabe der erforderlichen Werte kann das Spiel mithilfe des unteren Knopfs "Start!" erstellt werden.

Die Spielfeldoberfläche

spielfeldoberflaeche
Figure 5. Die Spielfeldoberfläche (hier mit dem Spiel "Piranhas")

Die Spielfeldoberfläche setzt sich aus dem Spielbrett (der große zentrale Bereich) und den Spielsteuerelementen (unten) zusammen.

Auf dem Spielbrett werden das eigentliche Spiel (hier z.B. "Piranhas"), die Züge und weitere für das Spiel wichtige Informationen dargestellt. Hier setzt der menschliche Spieler auch seine Züge.

Die Steuerelemente unterscheiden sich je nach Spiel und Spielsituation. Unten links gibt es immer die Schaltflächen "Abspielen/Pause", "Vor" und "Zurück". Mit diesen kann man die Züge des Spiels durchgehen (das ist am nützlichsten, wenn zwei Computerspieler gegeneinander spielen und man sich die Züge genau ansehen will). Rechts daneben gibt es noch einen Regler für die Abspielgeschwindigkeit und eine Anzeige des aktuellen Zuges. Ganz rechts ist die Schaltfläche zum Speichern des aktuellen Spiels als Replay-Datei, die man dann später wieder laden und das Spiel erneut ansehen kann.

Wenn ein menschlicher Spieler am Zug ist, werden ausserdem Schaltfächen zur Eingabe des Spielzuges angezeigt. Diese sind von Spiel zu Spiel sehr unterschiedlich.

Für das Spiel Piranhas:

  • Die Fische, die man ziehen kann, werden mit einem gelben Kasten markiert. Um einen Fisch zum ziehen auszuwählen, klickt man auf ihn. Der ausgewählte Fisch beginnt dann zu springen.

  • Nach Auswahl eines zu ziehenden Fisches werden die möglichen Zielfelder mit einem gelben Kasten markiert. Um den Fisch auf ein mögliches Feld zu ziehen, klickt man es an. Der Fisch zieht auf das angeklickte Feld und der Zug ist beendet.

  • Möchte man nach Auswahl eines Fisches doch einen anderen Fisch ziehen, klickt man irgendwo auf dem Spielbrett, nur nicht auf eines der markierten Zielfelder. Dann wird der Fisch wieder abgewählt und man kann erneut einen zu ziehenden Fisch auswählen.

Spielwiederholungen

Spielwiederholungen oder Replay-Dateien sind aufgezeichnete frühere Spiele, die man sich beliebig oft wieder ansehen kann, um beispielsweise einen Fehler des eigenen Spielers zu analysieren oder eine Strategie zu verbessern.

Um das aktuelle Spiel als Spielwiederholung zu speichern, klickt man auf das Icon ganz rechts unten im Spielbereich. Dann kann man einen Dateinamen und Speicherort festlegen.

Um eine gespeicherte Spielwiederholung zu laden verwendet man den Eintrag "Replay laden" in der linken Leiste. Nachdem man eine Datei ausgewählt hat, kann man das gespeicherte Spiel abspielen oder Schritt für Schritt durchgehen.

Testdurchläufe

Wenn man einen grundsätzlich funkionierenden Computerspieler programmiert hat, ist es sinnvoll, diesen mit vielen verschiedenen Spielsituationen zu konfrontieren. Dadurch lassen sich Fehler entdecken und die Spielstärke des Computerspielers beurteilen. Für solche Testdurchläufe wird ein Testserver und TestClient zur Verfügung gestellt. Wie man diese verwendet, ist weiter unten unter den Überschrift Automatische Spiele: Der Testserver und Massentests beschrieben.

Spielsituation nachstellen

Wenn Sie ein Fehlerverhalten Ihres Computerspielers beobachtet haben, das nur in einer bestimmten Situation in einem Spiel aufgetreten ist, kann es oft wünschenswert sein, diese Situation erneut nachspielen zu können, um den Computerspieler gezielt zu verbessern.

Dies ist zur Zeit nur auf etwas kompliziertem Wege möglich. Es folgt eine Schritt-für-Schritt Anleitung:

  1. Laden Sie das betreffende Replay aus dem Wettkampfsystem herunter (.xml.gz Datei).

  2. Entpacken Sie das Replay, sodass sie eine .xml-Datei erhalten.

  3. Starten Sie den Server und erstellen Sie ein neues Spiel. Wählen Sie den Computerspieler, der für diese Spielsituation getestet werden soll. Dieser Spieler muss als Spieler 1 gestartet werden und ist dann direkt als erstes dran. Der Gegenspieler kann dann ein beliebiger Computerspieler oder auch ein Mensch sein.

  4. Setzen Sie einen Haken bei "Spiel aus Datei laden". Wählen Sie über "Datei wählen" das entsprechende Replay aus und spezifizieren sie den Zug in dem gestartet werden soll. Starten Sie dann das Spiel. Das Spiel sollte sich nun in genau der Situation befinden, in der das Fehlerverhalten aufgetreten ist. Dabei ist der Spieler, der nun dran ist immer der rote Spieler. Falls der blaue Spieler eigentlich dran war, werden die Farben der Spieler getauscht.

  5. Nun kann der nächste Zug beim Spieler angefordert werden und dabei durch Debugging kontrolliert werden, wo sich der Spieler falsch verhalten hat. Achtung: Wenn weitere Züge angefordert werden, kann das Verhalten vom normalen Spielverlauf abweichen, da evtl. nicht alle Daten für das Spiel in der XML vorhanden sind.

Replay mit Server ohne graphische Oberfläche speichern

Wenn der Server ohne die graphische Oberfläche gestartet wird, kann das --saveReplay Attribut gesetzt werden, damit bei Ende jedes Spiels das Replay des Spiels unter ./replays gespeichert wird.

  java -Dfile.encoding=UTF-8 -Dlogback.configurationFile=logback.xml -jar softwarechallenge-server.jar --port 13051 --saveReplay true

Automatische Spiele: Der Testserver

Wenn Sie automatisiert Spiele mit Ihrem Computerspieler spielen wollen, um bestimmte Verhaltensweisen bei der Weiterentwicklung regelmäßig zu testen, können Sie dafür einen speziellen Server ohne grafische Oberfläche verwenden, den sogenannten Testserver. Hier ist zu beachten, dass der Testserver auf dem Port 13051 gestartet wird und nicht, wie im normalen Spiel auf Port 13050.

Gehen Sie dazu wie folgt vor:

  1. Laden Sie den Testserver von der Download-Seite herunter.

  2. Entpacken Sie das heruntergeladene Archiv.

  3. Wechseln Sie in einer Kommandozeilenumgebung (Windows: cmd.exe oder Powershell, Linux: beliebige Shell oder Terminal) in das Verzeichnis des entpackten Archives.

  4. Starten Sie den Testserver auf dem Port 13051 mit folgendem Befehl:

      java -Dfile.encoding=UTF-8 -Dlogback.configurationFile=logback.xml -jar softwarechallenge-server.jar --port 13051
  5. Starten Sie Ihren Computerspieler und einen zweiten Computerspieler manuell auf dem Port 13051 (im SimpleClient geht dies mit der Option --port 13051) in weiteren Kommandozeilenumgebungen. Die Computerspieler verbinden sich automatisch zum Testserver und es wird ein Spiel gespielt. Danach sollten sich die Computerspieler automatisch beenden.

  6. Wenn Sie weitere Testspiele starten wollen, können Sie die Computerspieler erneut starten. Der Testserver muss nicht neu gestartet werden.

Beachten Sie, dass der Testserver keine Spielaufzeichnungen anlegt, wie es der Server mit grafischer Oberfläche tut. Die Auswertung der Spiele muss in einem der teilnehmenden Computerspieler geschehen (z.B. durch Log-Ausgaben).

Es ist ebenfalls möglich, statt eines Zufällig generierten vollständigen Spielplanes eine Spielsituation zu laden und zu testen. Die Spielsituation muss vorher wie unter Spielsituation nachstellen erzeugt werden. Dann kann die Datei mit dem Argument --loadGameFile geladen werden und optional mit --turn ein Zug spezifiziert werden.

  java -Dfile.encoding=UTF-8 -Dlogback.configurationFile=logback.xml -jar softwarechallenge-server.jar --port 13051 --loadGameFile ./replay.xml --turn 10

Unerwartete Zugzeitüberschreitungen (Soft-Timeout)

Wenn Sie den Testserver einige Zeit laufen lassen, um eine größere Anzahl von Testspielen durchzuführen, kann es dazu kommen, dass Computerspieler wegen Zugzeitüberschreitungen vom Server disqualifiziert werden (Soft-Timeout). Dies passiert, obwohl sie ihren Zug innerhalb der erlaubten Zugzeit (abhängig vom Spiel, bisher aber immer zwei Sekunden) an den Server geschickt haben. Der Garbage Collector der Java Virtual Machine löst dieses Verhalten aus. Er pausiert die Anwendung, um nicht mehr genutzten Speicher freizugeben. Wenn der Server dadurch zu einem ungünstigen Zeitpunkt angehalten wird, bemerkt er den Eingang des Zuges vom Computerspieler nicht rechtzeitig und disqualifiziert ihn daraufhin. Damit dieses Problem möglichst selten auftritt, haben sich die folgenden Parameter beim Starten des Servers bewährt:

Unter Linux:

java -Dfile.encoding=UTF-8 \
     -Dlogback.configurationFile=logback.xml \
     -server \
     -XX:MaxGCPauseMillis=100 \
     -XX:GCPauseIntervalMillis=2050 \
     -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled \
     -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 \
     -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark \
     -jar softwarechallenge-server.jar --port 13051

Unter Windows (unterscheidet sich nur durch die Art, den langen Befehl auf mehrere Zeilen zu verteilen):

java -Dfile.encoding=UTF-8 ^
     -Dlogback.configurationFile=logback.xml ^
     -server ^
     -XX:MaxGCPauseMillis=100 ^
     -XX:GCPauseIntervalMillis=2050 ^
     -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled ^
     -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 ^
     -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark ^
     -jar softwarechallenge-server.jar --port 13051

Um das Verhalten des Garbage Collectors noch weiter zu verbessern, kann man auch noch mittels der Optionen

-XX:+PrintGCDateStamps -XX:+PrintGC -XX:+PrintGCDetails -Xloggc:"pfad_zum_gc.log"

eine Logdatei über die Aktivitäten des Garbage Collectors anlegen. Darin sieht man genau, wann er wie lange lief. Man kann dann die Einstellungen verändern und testen, ob sich das Verhalten verbessert.

Die Konfiguration des Garbage Collectors ist kein Allheilmittel und kann zu neuen Problemen führen, auf die man gefasst sein sollte. Dazu gehören erhöhter Resourcenverbrauch und Instabilität der Anwendung.

Massentests mit Server ohne graphische Oberfläche

Wenn Sie Massentests mit ihrem Computerspieler ausführen wollen, um Beispielsweise seine Gewinnchance gegenüber einer früheren Version zu testen, wobei sich die beiden Spieler als Startspieler abwechseln, gibt es zwei Varianten:

Variante mit TestClient

Starten sie den TestClient:

java -jar -Dlogback.configurationFile=logback-tests.xml test_client.jar
    --tests 4
    --name1 "displayName1"
    --player1 "./player1.jar"
    --name2 "displayName2"
    --player2 "./player2.jar"
    --start-server
    --port 13051
Sie können hier auch manuell einen Server vorher starten, wie bei der Variante ohne TestClient, allerdings kümmert der TestClient sich bei Angabe des Arguments --start-server gleich selber darum. Sie sollten lediglich aufpassen, dass nicht zwei Server auf dem selben Port laufen.
Argumente des TestClients
Attribut Standardwert (Typ) Kurzbeschreibung

--tests

100 (int)

Anzahl der Tests, die gespielt werden sollen

--player1

"./defaultplayer.jar" (Dateipfad)

Erster Computerspieler

--player2

"./defaultplayer.jar" (Dateipfad)

Zweiter Computerspieler

--name1

"player1" (String)

Name des ersten Spielers

--name2

"player2" (String)

Name des zweiten Spielers

--no-timeout

false (bool)

Deaktiviere ausscheiden durch Timeouts. Kann durch --no-timeout1 bzw. --no-timeout2 für beide Spieler unabhängig gesetzt werden.

--start-server

false (bool)

Starte einen Server auf dem angegebenen Port vor dem Starten der Clients

--port

13051 (int)

Der Port, auf dem der TestClient die Clients startet

--host

localhost (IP)

Das Gerät, auf dem der Server läuft

--loglevel

INFO - as defined in logback XML (Level)

Setzt das Loglevel, um ausführliche oder besonders kompakte Ausgaben zu erhalten.

Boolesche Parameter werden als true gewertet, sobald sie angegeben werden. Ein Wert hinter dem Parameter hat keine Wirkung.

Bei Argumenten, die nicht angegeben wurden, werden die Standardwerte aus der Tabelle verwendet. Die Ausgabe der Daten erfolgt nach jedem Spiel anhand von gerundeten Werten. Der TestClient beendet sich selbst, nachdem alle Spiele gespielt wurden.

Die Ergebnisse der Spiele werden für den jeweiligen Spielernamen vom Server zusammengezählt. Dies wird auch über mehrere Starts des TestClients getan. Die Ergebnisse werden erst zurückgesetzt, wenn der Server neu gestartet wird. Achten Sie also darauf, den Server neuzustarten oder einen anderen Spielernamen zu verwenden, wenn Sie den Spieler verändern.

Variante ohne TestClient

Starten sie den Server:

java -Dfile.encoding=UTF-8 -Dlogback.configurationFile=logback.xml -jar softwarechallenge-server.jar --port 13051

Starten Sie ein Spiel mit Reservierungscode (siehe Spielverlauf in der XML-Dokumentation). Aktivieren Sie mit dem erstellten Administratorclient den Testmodus:

<testModus testModus="true"/>

Dies liefert die Antwort

<testing testModus="true"/>

Mit false als entsprechenden Parameter kann dieser wieder deaktiviert werden. Nun können sie jederzeit die Testdaten der Spieler anhand ihres Anzeigenamens erfragen (es ist zu beachten, dass dafür die Spieler unterschiedliche Anzeigenamen haben müssen):

<scoreForPlayer displayName="player1" />

Der Server antwortet mit:

<playerScore>
  <score displayName="player1" numberOfTests="4">
    <values>
      <fragment name="Gewinner">
        <aggregation>SUM</aggregation>
        <relevantForRanking>true</relevantForRanking>
      </fragment>
      <value>4</value>
    </values>
    <values>
      <fragment name="∅ Feldnummer">
        <aggregation>AVERAGE</aggregation>
        <relevantForRanking>true</relevantForRanking>
      </fragment>
      <value>5.0000013</value>
    </values>
    <values>
      <fragment name="∅ Karotten">
        <aggregation>AVERAGE</aggregation>
        <relevantForRanking>true</relevantForRanking>
      </fragment>
      <value>40.500011</value>
    </values>
  </score>
</playerScore>

Bei dieser Variante muss sich selbst um das Starten der Clients gekümmert werden.