Dokumentation Cluedo

Werbung
Dokumentation Cluedo-Protokoll
Protokoll Version 1.3
Sebastian Bschorer ∗
27. Juli 2015
Änderungen gegenüber früheren Versionen
Neu in Version 1.3
• Die "poolcards"-Nachricht unter 9.3 muss selbstverständlich die GameId beinhalten.
• Nach einem erfolgreichen Login 5.2 können die "person positions" und "weapon positions"
in den Spielinfos noch fehlen.
Hinweis: Aufgrund der nahen Abgabetermine ist der Testserver weiterhin mit Versionsnummer 1.2.1 kompatibel, die jedoch intern schon mit 1.3 arbeitet.)
Neu in Version 1.2.1
• Die "game started"-Nachricht unter 8.5 wird an alle verbundenen Clients gesendet und nicht
nur an die Spielteilnehmer.
• Selbiges gilt auch für die "game ended"-Nachricht unter 8.6.
Hinweis: Bei dieser Protokolländerungen müssen keine JSON-Nachrichten umgebaut werden. Lediglich
die Versionsnummer muss geändert werden. Daher auch die Art der Versionsnummerierung. Das soll vor
allem sicherstellen, dass die Protokolländerung wahrgenommen wurde.)
Neu in Version 1.2
• Der Spielerzustand in 6.7 wird als Array übergeben. In diesem Array sind alle aktuellen Spielzüge enthalten, die der Spieler machen darf. Ein Statusupdate sollte immer an alle Spielteilnehmer
versendet werden.
• "nick" und "playerstate" in stateupdate (9.1) wurden entfernt und durch ein "player"Objekt ersetzt.
• Der Testserver wurde bereitgestellt (vgl. 4).
∗
Basierend auf dem Catan-Protokoll von Erich Schubert und Johannes Lohrer, WiSe 14/15
1
Neu in Version 1.1
• Nachrichten für den UDP-Handshake spezifiziert (vgl. 5.1).
• Würfelwurf unter 9.2 als Array von zwei Würfeln festgelegt.
• In der Spielerinfo wird die Kartenanzahl und die Spielfeldposition nicht mehr übergeben.
• Stattdessen gibt es eine neue Version der Spielinfo (vgl. 6.6).
• Tritt ein Zuschauer einem Spiel bei, erhält er eine Spielinfo-Nachricht (vgl. 8.3).
• Der Aufbau einer "moved"-Nachricht wurde umgeschrieben. (vgl. 9.3)
• Der Typ von "jsonID" unter 7.1 wurde als positive Ganzzahl spezifiziert.
• Ein Client kann in demselben Spiel nicht Spieler und Zuschauer gleichzeitig sein.
• Es wurde festgelegt, dass der Server ein Spiel beendet, falls ein Spieler das Spiel vorzeitig verlässt.
2
1 Grundlagen
Die Daten werden über einen persistenten TCP-Stream übertragen. Der Port ist dabei nicht festgelegt. Das Protokoll verwendet einen Strom von JSON-Objekten, als Zeichensatz wird dabei UTF-8
verwendet. Objekte müssen dabei so kodiert werden, dass sie selbst keine Zeilenwechsel enthalten
(optionale Zeilenwechsel müssen weggelassen werden, in Zeichenketten verwenden Sie "\n"). Ein
Zeilenwechsel darf ausschließlich als Trennsymbol für Objekte verwendet werden (gestalten Sie aber
ihren Parser hierfür möglichst tolerant, damit er auch mit fehlerhaften Nachrichten umgehen kann).
Nach jedem Objekt müssen Sie einen Zeilenwechsel schicken.
Unterschiedliche Nachrichtentypen sind durch sogenannte Wrapper-Objekte modelliert.
Ein Objekt darf dabei stets nur eine Nachricht enthalten.
Die allgemeine Form einer Nachricht sieht folgendermaßen aus:
{ "type"
: String,
"Attribut"
: "Wert",
"2. Attribut" : "Wert"
}
Statt einem primitiven "Wert" können hier jedoch auch komplexere JSON-Objekte auftreten. Zeilenwechsel müssen bei der Serialisierung weggelassen oder kodiert werden, so dass die Nachricht dann
beispielsweise wie folgt verschickt wird:
{"type":String, "Attribut":"Wert","2. Attribut":"Wert"}
2 Kompatibilität
Ihre Implementierung braucht nur die neueste Protokollversion unterstützen. Momentan handelt es
sich dabei um Version "1.3".
Ihr Client soll mit jedem Server funktionieren, der dieses Protokoll korrekt implementiert. Ebenso soll
ihr Server (zumindest im Kompatibilitätsmodus) mit jedem Client spielbar sein. Insbesondere gilt dies
für die KI-Spieler.
Eigene Erweiterungen können Sie gerne vornehmen, allerdings muss ihr Client und Server über einen
Kompatibilitätsmodus verfügen, der Interoperabilität gewährleistet.
3
3 Hinweise zu JSON
• Verlassen Sie sich nicht darauf, dass ein einzelner read() Aufruf die vollständige Nachricht liefert. Das Betriebssystem kann die Nachrichten fragmentiert übertragen. Füllen Sie einen Puffer
so lange, bis die empfangene Nachricht ein vollständiges JSON-Objekt ergibt (ein korrekter
Server sollte anschließend auch einen Zeilenwechsel senden).
• Die Verwendung von Bibliotheken wie JSON.org, Jackson, GSON, etc. hierfür ist sinnvoll. Keinesfalls sollte das Protokoll manuell per print erzeugt werden.
• Beachten Sie die UTF-8 Kodierung von Umlauten. Empfehlenswert ist es, Ihr gesamtes Projekt
in Eclipse als UTF-8 zu konfigurieren, um Probleme mit Windows zu vermeiden (OSX und Linux
verwenden normalerweise bereits UTF-8).
4 Testserver
Im CIP-Pool ist ab sofort ein Testserver verfügbar mit dem Sie ihre Implementierung testen können.
Innerhalb des MWN-Netzes1 ist es möglich, über den Port 30305 eine Verbindung zum Server mit der
Adresse vanuabalavu.pms.ifi.lmu.de aufzunehmen.
Um schnelleres Testen zu ermöglichen, kann ein Spiel schon gestartet werden, wenn nur ein Spieler
dem Spiel beigetreten ist.
Da nicht auszuschließen ist, dass der Server fehlerfrei läuft, teilen Sie bitte frühzeitig mit, wenn Sie
ein Fehlverhalten vermuten. Ist der Server nicht verfügbar, so probieren Sie es bitte später nochmals.
Gerne an mich per Mail an [email protected].
1
Sie können auch von zu Hause aus eine Verbindung zum Testserver aufbauen, wenn Sie im Vorfeld eine VPN-Verbindung
in das MWN-Netz herstellen. Informationen dazu finden Sie unter https://www.lrz.de/services/netz/mobil/
vpn/anyconnect/.
4
5 Verbindungsaufbau
5.1 UDP-Handshake
Um das Verbinden zu einem Server im lokalen Netz zu vereinfachen, soll es möglich sein, einen UDPHandshake durchzuführen. Server und Client kommunizieren dabei über den Port 30303. Dieser ist
laut IANA nicht zugewiesen und daher frei.
Wenn ein UDP-Server gestartet wird, soll er sich mit folgender Nachricht über Broadcasts im Netzwerk bemerkbar machen:
{"type":"udp server","group":String,"tcp port":int}
Bei "group" handelt es sich dabei um den Gruppennamen. Laufende Clients können diese Nachricht
über UDP empfangen und erhalten dadurch den "tcp port" für die TCP-Verbindung zum Server.
(Dieser muss sich vom UDP-Port unterscheiden!) Die dazugehörige IP kann der Client aus dem eingehenden Datenpaket auslesen.
Wird ein Client gestartet, kann er mittels folgender Nachricht nach Servern im lokalen Netz suchen:
{"type":"udp client","group":String}
Ein Server, der diese Nachricht empfängt, antwortet mit der bereits oben spezifizierten Nachricht.
Mit der IP-Adresse und dem TCP-Port kann ein Client anschließend eine TCP-Verbindung zum Server
aufbauen. Sind mehrere Server im lokalen Netz verfügbar, so kann der Client auswählen, zu welchem
er sich verbinden möchte.
Achtung: Die UDP-Broadcasts funktioniert nur im lokalen Netz. Ein Client sollte daher auch die Möglichkeit haben, IP-Adresse des Servers sowie den Port manuell einzugeben.
5.2 Login am Server
Steht die TCP-Verbindung, so ist der Client zunächst noch nicht angemeldet. Der Server reagiert in
diesem Zustand nur auf die Nachricht "login" und sendet selbst keinerlei Nachrichten an diesen
Client. Eine "login" ist nach folgendem Schema aufgebaut:
{
"type" : "login",
"nick" : String,
"group" : String,
"version" : "4.2",
"expansions" : [ String ]
}
"nick" repräsentiert den Benutzername. Er darf jedes beliebige UTF-8-Zeichen enthalten, muss jedoch mindestens drei Zeichen lang sein. Bei "group" wird der Gruppenname erwartet. Bei "version"
handelt es sich um die Protokollversionsnummer und wird als String repräsentiert. "expansions"
enthält ein Array aller Erweiterungen, die der Client beherrscht. Werden keine Erweiterungen unterstützt, so kann dieser Eintrag in der Nachricht fehlen.
5
Beispielhaft könnte eine login-Nachricht so aussehen:
{
"type" : "login",
"nick" : "Sepp",
"group" : "TestendeTentakel",
"version" : "1.2.1",
"expansions" : [ "Chat", "HyperHyperFeature" ]
}
War der Login erfolgreich, so antwortet der Server diesem Client mit einer "login successful"Nachricht.
{
"type" : "login successful",
"expansions" : [ String ],
"nick array" : [ String ],
"game array" : [ SpielInfo ]
}
Die Nachricht enthält als "expansions" die maximale Teilmenge der Fähigkeiten enthält, die sowohl
Client als auch Server haben. In der Basisversion des Protokolls müssen sowohl Client als auch Server mindestens eine Chat-Fähigkeit haben, welche mit dem Namen "Chat" bezeichnet wird (vgl. 7.2).
Die Nachricht besitzt ein String-Array, welches die Nutzernamen aller angemeldeten Clients enthält.
Außerdem wird ein Array aus Spielinfos mit dieser Nachricht übertragen. Dieses Array soll alle momentan verfügbare Spiele des Servers enthalten. Der Aufbau einer Spielinfo ist unter 6.6 erklärt. Die
Attribute "person positions" und "weapon positions" dürfen hierbei noch fehlen.
Alle anderen angemeldeten Clients erhalten vom Server eine Nachricht der Form:
{"type":"user added","nick":String}
Wird ein Client beendet, sollte er sich beim Server abmelden mittels:
{"type":"disconnect"}
Bevor die Socket-Verbindung abgebrochen wird, reagiert der Server mit einem abschließenden:
{"type":"disconnected","message":String}
Alle anderen Clients werden darüber informiert:
{"type":"user left","nick":String}
Sollte es laufende Spiele geben, denen dieser Client beigetreten war, so beendet der Server das Spiel
und schickt an alle Clients eine "game ended"-Nachricht (vgl. 8.6).
6
6 Objekte
Nachrichten können verschiedene Objekte enthalten. Diese werden als JSON-Objekte übertragen.
6.1 Spielfeld
Das Spielfeld ist folgendermaßen definiert und besitzt (mit Ausnahme des Schwimmbads) den gleichen
Aufbau wie die älteren Brettspielversionen:
y-Achse
x-Achse
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Eingangshalle
Arbeitszimmer
Salon
S
W
S
S S
Bibliothek
N
O
N
O
S
Schwimmbad
N
W
Billardzimmer
W
Speisezimmer
S
O
N
N
N
O
Wintergarten
W
O
Musikzimmer
Küche
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
7
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
6.2 Felder
Jedes Quadrat repräsentiert ein begehbares Feld und wird als ein Objekt mit einer "x"- und einer
"y"-Koordinate repräsentiert:
{"x" : 15, "y" : 16}
Folgende Feldertypen sind definiert:
• Auf hellen Feldern können sich die Spielfiguren bewegen. Auf jedem dieser Felder darf sich
maximal eine Spielfigur gleichzeitig befinden.
• Die sechs farbigen Felder bestimmen die Startpositionen der einzelnen Farben. Rot zum Beispiel besitzt die Startposition (16, 0). Abgesehen davon handelt es sich bei Ihnen um reguläre
Spielfelder.
• Die Felder mit dem Buchstaben darin symbolisieren eine Tür in einen Raum. Die vier Buchstaben N, O, S, W bestimmen die Himmelsausrichtung der Tür. Auf diesen Feldern dürfen sich
beliebig viele Spielfiguren befinden.
Das Arbeitszimmer kann beispielsweise nur von Süden aus, von (6, 4) → (6, 3) betreten werden. Die Felder (7, 3) und (6, 3) sind nicht benachbart.
Landet eine Spielfigur auf einer Tür, so hat sie den Raum betreten.
Räume an sich sind keine begehbaren Spielfelder, begrenzen aber durch ihre Anwesenheit das Spielfeld. Ein Raum ist definiert durch die Menge der Türen, die in diesen Raum führen.
Der Spielfeldaufbau (samt Startpositionen) ist statisch und muss daher nicht über das Netzwerk kommuniziert werden.
6.3 Farben
Es werden im Grundspiel sechs verschieden Farben unterstützt. In Nachrichten mit dem Attribut
"color" darf die Farbe eine der folgenden Werte annehmen: "red", "yellow", "white", "green",
"blue" oder "purple".
6.4 Karten
Es wird zwischen drei Kartentypen unterschieden: person, weapon und room. Im Grundspiel dürfen
folgende Werte angenommen werden:
Personen:
"red"
"yellow"
"white"
"green"
"blue"
"purple"
Fräulein Gloria
Oberst von Gatow
Frau Weiß
Reverend Grün
Baronin von Porz
Professor Bloom
8
Waffen:
"dagger"
"candlestick"
"revolver"
"rope"
"pipe"
"spanner"
Dolch
Leuchter
Revolver
Seil
Heizungsrohr
Rohrzange
Räume:
"hall"
"lounge"
"diningroom"
"kitchen"
"ballroom"
"conservatory"
"billiard"
"library"
"study"
"pool"
Eingangshalle
Salon
Speisezimmer
Küche
Musikzimmer
Wintergarten
Billardzimmer
Bibliothek
Arbeitszimmer
Schwimmbad
Wird, wie unter 6.7 ein Array von Karten verlangt, so kann eine Karte entweder eine Person, eine
Waffe oder ein Raum sein.
6.5 Aussagen
Aussagen, wie sie bei Verdächtigungen und Anklagen verwendet werden, haben folgende Form:
{
"person" : Person,
"weapon" : Waffe,
"room" : Raum
}
Das Schwimmbad oder "pool" spielt eine Sonderrolle. In diesem Raum kann kein Mord stattfinden.
Daher darf er auch nicht in einer Aussage auftauchen.
6.6 Spielinfo
Eine Spielinfo soll den aktuellen Zustand über ein Spiel enthalten. Sie hat folgenden Aufbau:
{
"gameID" : int,
"gamestate" : Spielzustand,
"players" : [ Spielerinfo ],
"watchers" : [ String ],
"person positions" : [ Personenposition ]
"weapon positions" : [ Waffenposition ]
}
9
Spielzustand
Der Spielzustand darf einen der Werte "not started", "started" oder "ended" annehmen.
watchers enthält ein Array aus Nicknames derjeniger Clients, die diesem Spiel zuschauen.
6.7 Spielerinfo
Die Informationen über einen Spieler sehen folgendermaßen aus:
{
"nick" : String,
"color" : Farbe,
"playerstate" : [Spielerzustand]
}
Wenn das Spiel noch nicht gestartet wurde, kann das Attribut "playerstate" auch fehlen oder null
sein.
Spielerzustand
Der Spielerzustand gibt Aufschluss darüber, welche Aktionen der Server von einem Spieler als
nächstes erwartet. Hat ein Spieler mehrere Möglichkeiten, so werden alle Möglichkeiten übergeben.
Folgende Statusmeldungen sind spezifiziert:
"do nothing"
"roll dice"
"use secret passage"
"move"
"suspect"
"accuse"
"disprove"
"end turn"
Der Spieler muss warten.
Der Spieler darf würfeln.
Der Spieler darf den Geheimgang benutzen.
Der Spieler muss seine Figur bewegen.
Der Spieler darf eine Verdächtigung äußern.
Der Spieler darf anklagen.
Der Spieler muss auf eine Verdächtigung reagieren.
(Entweder widerlegen oder mitteilen,
dass er nicht widerlegen kann.)
Der Spieler darf den Spielzug beenden.
6.8 Personenposition
Das Unwort Personenposition beschreibt nichts anderes als das Tupel aus Person und dem Feld, auf
dem sich diese Person befindet. Sie hat diesen Aufbau:
{ "person" : Person, "field" : Feld }
6.9 Waffenposition
Analog zu oben gibt eine Waffenposition wieder, wo eine Waffe auf dem Spielfeld liegt. Wichtig ist
hierbei aber, dass sich Waffen nur in Räumen (also auf Türfeldern) befinden können.
{ "weapon" : Waffe, "field" : Feld }
10
7 Allgemeine Nachrichten
7.1 Bestätigungen und Fehler
Der Server muss jede Aktion des Clients bestätigen. Wenn eine Aktion des Spielers nicht erfolgreich
durchgeführt werden konnte, so muss ein Fehler verschickt werden (Sie werden sich aber nicht darauf
verlassen können, dass jeder Server die gleichen Meldungen verschickt). Hat eine Aktion weitere
Nachrichten zur Folge, so sollen erst die anderen Nachrichten verschickt werden, abschließend dann
eine "ok"-Nachricht:
{"type":"ok"}
Kommt es bei der Verarbeitung einer einkommenden Nachricht vom Client zu einem Fehlerfall, so
sendet der Server eine Nachricht vom Typ "error" an diesen Client zurück:
{"type":"error","message":"..."}
Diese Fehlermeldung werden zum Beispiel auch versandt, wenn ein Spieler einen ungültigen Spielzug
durchführen will. Sie können nicht davon ausgehen, dass alle Server dieselben Fehlernachrichten
versenden.
Jeder beliebigen Nachricht an den Server kann ein Attribut "jsonID" vom Typ int beigefügt werden,
wobei es sich dabei um einen positiven Wert handeln muss. Der Server verwertet diese ID nicht.
Wenn sie allerdings in einer ankommenden Nachricht vorhanden ist, wird sie in einer "ok"- oder
"error"-Nachricht als Attribut wieder an den Client zurückgeschickt.
7.2 Chat
Jeder Server muss mindestens eine Chat-Erweiterung implementieren, die den Namen "Chat" besitzt
und in den ""expansions" (vgl.5) aufgeführt wird.
Um eine Chat-Nachricht an die Mitspieler zu senden verwenden Sie folgende Nachricht:
{"type":"chat","message":String,"timestamp":Zeitstempel}
Soll eine Nachricht nicht an alle, sondern nur an ein bestimmtes Spiel gesendet werden fügen Sie
ein Attribut "gameID" mit der Spielnummer hinzu. Ist eine Nachricht nur einen bestimmten User
gedacht, fügen Sie ein Attribut "nick" mit dem Nickname hinzu.
Schickt ein Client eine Chatnachricht, so wird diese vom Server verteilt.
{
"type" : "chat",
"sender" : String,
"message" : String,
"timestamp" : Zeitstempel
}
Verschickt der Server eine Chatnachricht, so fehlt das Attribut "sender".
Für den Zeitstempel soll die String-Repräsentation eines java.time.LocalDateTime-Objekts verwendet werden, das die Form besitzt: "2015-04-08T15:16:23.42"
11
8 Konfiguration und Spielstart
8.1 Ein Spiel erstellen
Der Server soll die Möglichkeit bieten, beliebig viele Spiele parallel verwalten zu können. Um ein
neues Spiel zu erstellen, schickt der Client die Nachricht:
{
"type" : "create game",
"color" : Farbe
}
Der Client tritt dem Spiel dabei gleichzeitig als Spieler mit der Farbe "color" bei. Der Server sendet
daraufhin an alle Clients die Nachricht
{
"type" : "game created",
"gameID" : int,
"player" : SpielerInfo
}
8.2 Einem Spiel als Spieler beitreten
Anschließend können Clients folgendermaßen bei diesem Spiel beitreten:
{
"type" : "join game",
"gameID" : int,
"color" : Farbe
}
Der Server sendet daraufhin an alle Clients:
{
"type" : "player added",
"gameID" : int,
"player" : SpielerInfo
}
8.3 Einem (laufenden) Spiel als Zuschauer beitreten
Man kann einem Spiel auch als Zuschauer beitreten. Allerdings nicht als Spieler und Zuschauer gleichzeitig.
{
"type" : "watch game",
"gameID" : int
}
12
Der Server sendet daraufhin an alle Clients:
{
"type" : "watcher added",
"gameID" : int,
"nick" : String
}
Der neu zuschauende Spieler erhält anschließend noch eine Spielinfo:
{
"type" : "gameinfo",
"game" : Spielinfo
}
8.4 Ein Spiel verlassen
Zuschauer und/oder Spieler können ein Spiel verlassen mit:
{"type":"leave game","gameID":int}
Daraufhin sendet der Server an alle Clients:
{
"type" : "left game",
"gameID" : int,
"nick" : String
}
Verlässt ein Spieler ein laufendes Spiel, beendet der Server dieses und schickt an alle Clients eine
"game ended"-Nachricht (vgl. 8.6).
Befinden sich in einem Spiel keine Spieler mehr, so löscht der Server das Spiel und sendet an die
Clients:
{"type":"game deleted","gameID":int}
8.5 Ein Spiel starten
Befinden sich 3-6 Spieler im Spiel und jeder hat eine andere Farbe gewählt, so kann jeder beliebige
dieser Spieler das Spiel starten mit:
{"type":"start game","gameID":int}
Im Erfolgsfall startet der Server das Spiel. Dabei wird jedem Spieler mitgeteilt, welche Karten er erhalten hat, z.B.:
{
"type" : "player_cards",
"gameID" : int,
"cards" : [ "candlestick", "diningroom", "ballroom", "yellow", "conservatory", "purple" ]
}
13
Anschließend schickt der Server an alle verbundenen Clients die Nachricht:
{
"type" : "game started",
"gameID" : int,
"gamestate" : "started",
"order" : [ "Sepp", "Josephine", "Sams" ]
}
Wichtig dabei ist, dass die Liste "order" vom Server gemischt wurde und ab sofort die Spielerreihenfolge festlegt. Der Spieler, der den ersten Spielzug beginnt, erhält abschließend einen Statusupdate
(vgl. 9.1).
8.6 Spielende
Das Spiel endet, sobald ein Spieler erfolgreich Anklage erhoben hat. Der Server versendet in diesem
Fall an alle Clients folgende Nachricht:
{
"type" : "game ended",
"gameID" : int,
"nick" : String,
"statement" : Aussage
}
"nick" ist dabei der Name des Gewinners. Die Aussage enthält die Lösung des Spiels. Haben alle
Spieler falsche Anklage erhoben oder endet das Spiel vorzeitig, so wird ebenfalls eine "game ended"Nachricht verschickt, allerdings fehlt in dieser dann der "nick".
14
9 Nachrichten des Servers im Spiel
9.1 Statusupdate eines Spielers
Wenn sich der Zustand eines Spielers ändert (beispielsweise er am Zug ist), so sendet der Server ein
Statusupdate an alle Spielbeteiligten. Diese Nachricht enthält den betreffenden Spieler und sein neuer
Status. Für alle anderen Spieler gilt ab dem Moment "do nothing".
{
"type" : "stateupdate",
"gameID" : int,
"player" : SpielerInfo
}
Diese Nachricht soll vom Server dazu genutzt werden, den allgemeinen Spielablauf (wer ist am Zug
etc.) zu steuern, insbesondere für KI-Spieler. Gültige Statusmeldungen hierfür sind im Abschnitt 6.7
spezifiziert. Insbesondere ist ein Status wie bspw. "roll dice" als Aufforderung zu sehen, den nächsten Zug zu machen.
9.2 Würfeln
Hat ein Spieler gewürfelt, so sendet der Server das Ergebnis.
{
"type" : "dice result",
"gameID" : int,
"result" : [ 3, 5 ]
}
9.3 Spielfigur bewegen
Hat ein Spieler seine Spielfigur bewegt, so sendet der Server die neue Position der Spielfigur:
{
"type" : "moved",
"gameID" : int,
"person position" : Personenposition
}
Falls der Spieler das Schwimmbad betreten hat, erhält er die Nachricht:
{
"type" : "poolcards",
"gameID" : int,
"cards" : [ Karte ]
}
15
9.4 Verdacht geäußert
Hat ein Spieler einen Verdacht geäußert, teilt der Server diesen an alle mit:
{
"type" : "suspicion",
"gameID" : int,
"statement" : Aussage
}
Anschließend fragt der Server den Spieler links vom aktiven Spieler mittels Statusupdate "disprove",
ob er die Verdächtigung widerlegen kann. Dieser muss daraufhin antworten (vgl. 10.5). Konnte der
Verdacht widerlegt werden, antwortet der Server mit dieser Nachricht:
{
"type" :
"gameID"
"nick" :
"card" :
"disproved",
: int,
String,
Karte
}
"nick" ist in diesem Fall derjenige Spieler, der den Verdacht widerlegen konnte. Wichtig: Nur derjenige, der die Verdächtigung geäußert hat, bekommt diese Karte zu sehen. Bei den übrigen Spielern
fehlt das Attribut "card".
Konnte der gefragte Spieler den Verdacht nicht widerlegen, frägt der Server reihum den nächsten.
Falls niemand den Verdacht widerlegen konnte, sendet der Server eine Nachricht im Format:
{
"type" : "no disprove",
"gameID" : int
}
Abschließend erhält der aktive Spieler einen entsprechenden Spielerzustand.
9.5 Anklage erhoben
Hat ein Spieler Anklage erhoben und lag dabei richtig, so endet das Spiel und der Server schickt die
Nachricht "game ended" an alle Spieler (vgl. 8.6).
War die Anklage falsch, so scheidet der Spieler als aktiver Spieler aus. Der Server sendet daraufhin
diese Nachricht an alle Spieler:
{
"type" : "wrong accusation",
"gameID" : int,
"statement" : Aussage
}
16
10 Nachrichten eines Spielers im Spiel
10.1 Würfeln
Um zu Würfeln, sendet der Spieler folgende Nachricht:
{
"type" : "roll dice",
"gameID" : int
}
10.2 Spielfigur bewegen
Um die eigene Spielfigur zu bewegen, wird an den Server folgende Nachricht geschickt:
{
"type" : "move",
"gameID" : int,
"field" : Feld
}
10.3 Geheimgang nutzen
Um den Geheimgang zu nutzen um in gegenüberliegende Räume zu gelangen, sendet der Spieler
folgende Nachricht:
{
"type" : "secret passage",
"gameID" : int
}
10.4 Verdächtigung äußern
Äußert der Spieler eine Verdächtigung, so hat eine entsprechende Nachricht an den Server diese Form:
{
"type" : "suspect",
"gameID" : int,
"statement" : Aussage
}
Da der Raum implizit durch die Position des Spielers abgeleitet werden kann, kann das Attribut
"room" in diesem Statement fehlen. (Nach Regel darf ein Verdacht nur in dem Raum ausgesprochen
werden, in welchem sich die eigene Spielfigur befindet).
17
10.5 Auf eine Verdächtigung reagieren
Wird man aufgefordert eine Verdächtigung zu widerlegen und kann sie auch widerlegen, so muss man
dies auch. Eine Nachricht hat dann diese Form:
{
"type" : "disprove",
"gameID" : int,
"card" : Karte
}
Kann eine Verdächtigung nicht widerlegt werden, so fehlt das Attribut "card".
10.6 Spielzug beenden
Der Spielzug kann beendet werden mit der Nachricht:
{"type":"end turn","gameID":int}
10.7 Anklagen
Eine Anklage wird folgendermaßen codiert:
{
"type" : "accuse",
"gameID" : int,
"statement" : Aussage
}
Anklagen sind an keinen Raum gebunden, daher darf hier (im Gegensatz zur Verdächtigung) "room"
als Argument nicht fehlen.
18
11 Hinweise
Hinweise zu den Spielregeln:
• Es gibt verschiedene Cluedo-Auflagen, die sich teilweise in ihren Regeln unterscheiden. Für
dieses Protokoll verwenden Sie die Anleitung, die Sie ebenfalls erhalten haben.
• Auch wenn die Regeln in der Grundversion bindend sind und so auch umgesetzt werden müssen, können und dürfen Sie gerne weitere, eigene Spielmodi einbauen. Achten Sie darauf, dass
diese in den "expansions" erscheinen.
• Der Notizblock wird in diesem Protokoll mit keinem Wort erwähnt! Selbstverständlich sollen
die Clients die Möglichkeit besitzen, sich auf einem „Block“ Notizen zu machen. Diese Notizen
müssen aber nicht an den Server übermittelt werden.
Hinweise zur Umsetzung in Java:
• Verwenden sie für JSON eine der vielen Bibliotheken, wie bspw. org.json, GSON oder Jackson.
• Konfigurieren Sie ihr Java-Projekt mit dem Zeichensatz UTF-8 (Projekteinstellungen). So vermeiden Sie Zeichensatzprobleme mit unterschiedlichen Betriebssystemen (Mac und Linux verwenden i.d.R. UTF-8, Windows die Windows-1252-Kodierung)
• Halten Sie sich an Java-Konventionen, insbesondere was Methoden-, Klassen-, Variablen- und
Konstantennamen betrifft. Vermeiden Sie dabei Sonderzeichen.
• Verwenden Sie Konstanten für häufige Zeichenketten, insbesondere für das Protokoll.
• Beobachten Sie ihre Systemlast. Wenn ihr Spiel eine moderne CPU zu 100% auslastet, haben
Sie eine fehlerhafte Schleife (Endlosschleife?) irgendwo in Ihrem Programm. Verwenden Sie
jvisualvm um herauszufinden, wo ihr Programm zu viel Rechenzeit verbraucht.
19
Herunterladen