next up previous
Up: Anforderungen

SWP'99
Protokolle und Datenformate


Inhalt

Notation

Zur Spezifikation von Mengen von Zeichenketten wird eine an die Backus-Naur-Form angelehnte Notation benutzt. Nichtterminale Symbole werden dabei als <id> geschrieben. Alternativen werden durch $\mid\ $getrennt. Zur Gruppierung wird $<\ldots>$ benutzt. Die n-fache Iteration wird durch $\ldots^n$ beschrieben. Mit $\ldots^*$ sind alle Iterationen mit $n
\geq 0$ bezeichnet, mit $\ldots^+$ alle mit n>0. Die leere Zeichenkette wird durch $\varepsilon$ repräsentiert. Um einen Buchstaben mit seiner ASCII-Kodierung x zu beschreiben, wird die Notation $\backslash x$ benutzt.

Um Protokolle zum bidirektionalen Datenaustausch nach dem Client-Server Pinzip zwischen Instanzen der einzelnen Rollen zu spezifizieren, wird folgende Syntax benutzt:

ctx: req $\mbox{\it\footnotesize c} \atop {\longleftrightarrow
\atop \mbox{\it\footnotesize s}}$ resp
Hierbei bezeichnet ctx den Kontext, in dem dieser Datenaustausch stattfindet. Er wird zur Referenzierung benötigt. Die Menge aller gültigen Anfragen wird mit req beschrieben, während resp alle gültigen Antworten beschreibt. Sie werden durch Grammatiken spezifiziert. Der Client, also die Instanz, die den Datenaustausch mit einer Anfrage anstößt, wird mit c charakterisiert, der Server mit s.

Da hier nur drei Rollen auftreten, die als Client oder als Server auftreten können, wird als Kurzschreibweise für den Spieler s, für den Verwalter v und für die Ausgabekanäle a benutzt. Sind mehrere Rollen als Client oder Server zulässig, werden mehrere Kürzel hintereinander geschrieben.

Für unidirektionale Kommunikation wird analog

ctx: req $\mbox{\it\footnotesize c} \atop {\longrightarrow
\atop \mbox{\it\footnotesize s}}$
geschrieben.

Während des Programmablaufes dürfen sich Aufrufe beliebig verschachteln. Das bedeutet, daß Server vor dem Senden ihrer Antwort beliebige weitere Anfragen als Client starten dürfen.

Repräsentation einer Spielfeldkachel

Eine Spielfeldkachel besteht aus 12 Reihen mit jeweils 12 Feldern und trennenden Wänden. Die untere Grammatik definiert eine Repräsentation einer Spielfeldkachel als Zeichenkette. Diese besteht aus 12 Reihen, welche die Bodenelemente mit ihren vertikalen Trennwänden charakterisieren, und 13 trennende Reihen zur Darstellung der horizontalen Trennwände. Zuerst werden die nördlichen Reihen ausgegeben. Die einzelnen Reihen werden mit Whitespaces (Leerzeichen, Zeilenende, Tabulatoren) getrennt.


<SFKachel>::= <SFKZwischenR><<SFKFeldR><SFKZwischenR>>12

<SFKZwischenR> ::= <Wand>12 <WS>
<SFKFeldR>::= <Wand> <<BodenInhalt><Wand>>12<WS>
<WS>::= $< {\backslash}10 \mid {\backslash}13 \mid {\backslash}32 >^+$
Eine Trennwand wird durch # dargestellt, gibt es keine Trennwand wird dies mit _ angezeigt. An einer Wand können auf beiden Seiten spezielle Vorrrichtungen (Geräte) befestigt sein. Wenn diese bei vertikalen Wänden links von # notiert sind, befinden sie sich auf dem Spielplan auf der linken Seite der Wand. Bei horizontalen Wänden befinden sie sich über der Wand. Sind sie auf der rechten Seite notiert, ist die Position entsprechend.

<Wand>::= <[<WandGerät>$\mid\ $$\varepsilon$><#$\mid\ $_><<WandGerät>]$\mid\ $$\varepsilon$>

An den Wänden können Laser oder Schieber befestigt sein.

<WandGerät>::= <Laser> $\mid\ $<Schieber>
Ein Boden kann leer sein oder ein Fließband, ein Drehelement, eine Grube oder ein Reparaturfeld beinhalten.

<BodenInhalt>::= <Boden>$\mid\ $<Fließband>$\mid\ $<DrehEl>$\mid\ $<Grube>$\mid\ $

<Reparaturfeld>


<Boden>::= B

Ein Laser hat eine Richtung, die durch seine Installation vorgegeben ist, und eine beliebige Stärke, welche die Anzahl von Schadenspunkten bei Kontakt mit dem Roboter darstellt.

<Laser>::= L(<N>)

<N>= 0 ...255
Ein Schieber hat eine Richtung, die durch seine Installation vorgegeben ist. Er wird in einer oder mehreren Registerphasen aktiv.

<Schieber>::= S(<<Registerphase>,>*)

<Registerphase>::= 1 $\mid\ $2 $\mid\ $3 $\mid\ $4 $\mid\ $5
Ein Fließband befördert einen Roboter in eine bestimmte Richtung mit einer bestimmten Geschwindigkeit. Hinzukommend kann der Roboter wie auf einem Drehelement gedreht werden, wobei die Drehrichtung abhängig ist von der Richtung, aus welcher der Roboter von einem Fließband auf das Feld geschoben wurde. Betritt der Roboter das Fließband aufgrund einer anderen Ursache, wird er nicht gedreht. Zusätzlich kann über dem Fließband ein Stampfer (Crusher) befestigt sein, der bei einer oder mehreren bestimmten Registerphasen aktiv wird und einen sich evt. auf dem Feld befindenden Roboter zerstört.

<Fließband>::= F(<Richtung>,<Geschwindigkeit>, 
( <(<Richtung>,<DrehEl>)>* )
( <<Registerphase>,>* ))
<Geschwindigkeit>::= 1 $\mid\ $2
<Richtung>::= N $\mid\ $E $\mid\ $S $\mid\ $W
Ein Drehelement dreht einen Roboter um 90 Grad entweder im Uhrzeigersinn (rechts) oder gegen den Uhrzeigersinn (links).

<DrehEl>::= D(<L$\mid\ $R>)
Eine Grube hat keine besonderen Eigenschaften.

<Grube>::= G 
Ein Reparaturfeld hat eine bestimmte Stärke, welche die Anzahl der reparierten Schadenspunkte kennzeichnet.

<Reparaturfeld>::= R(<N>)

   
Verwaltung

Registrierung

Vor Beginn des Spieles müssen sich alle teilnehmenden Spieler und die entsprechenden Ausgabekanäle registrieren. Falls dabei ein technisches Problem auftritt, gibt der Verwalter error zurück, ansonsten ok. Sollte der Verwalter sofort nach der Registrierung oder auch später entscheiden, daß kein freier Platz für den Spieler vorhanden ist, entfernt er ihn nachträglich (s. Abschn. 3.4).


Register: <Registrierung> $\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$<OK>

<Registrierung>::= RGS(<Name>) $\mid\ $RGA(<Name>)
<OK>::= ok $\mid\ $error

   
Spielstart

Wenn der Verwalter entscheidet, daß sich alle Spieler registriert haben, startet er das Spiel, indem er eine Nachricht an alle registrierten Spieler und Ausgabekanäle schickt. Dies dient nur zur Information. Spieler erhalten zusätzlich nach dieser Nachricht die Aufforderung eine Zugabgabe <MkNeuerRob> durchzuführen.


Spielstart: <NtfSpStart> $\mbox{\it\footnotesize v} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize sa}}$<OK>

<NtfSpStart>::= NTS

Abmeldungen

Sollte ein menschlicher Spieler kein Interesse mehr an der weiteren Teilnahme des Spieles haben oder ein künstlicher Spieler oder ein Ausgabekanal interne Probleme haben, kann er sich vom aktuellen Spiel abmelden. Der Spieler bzw. der Ausgabekanal identifiziert sich dabei mit seinem Namen.


Abmeldung: <AbmeldungReq> $\mbox{\it\footnotesize sa} \atop {\longrightarrow \atop \mbox{\it\footnotesize v}}$

<AbmeldungReq>::= RLE(<Name>)
Spieltechnisch gilt für einen Spieler eine Abmeldung wie der sofortige Verlust aller restlichen Leben.

   
Entfernung

Ein Spieler (S) oder ein Ausgabekanal (A) kann von dem Verwalter aus dem aktuellen Spiel entfernt werden. Dafür kann es unterschiedliche Gründe geben:


Entfernung: <EntfernungReq> $\mbox{\it\footnotesize v} \atop {\longrightarrow \atop \mbox{\it\footnotesize sa}}$

<EntfernungReq>::= REN(<EntfernungReqGrund>)
<EntfernungReqGrund>::= LL $\mid\ $TO $\mid\ $GO $\mid\ $RV $\mid\ $ZS $\mid\ $
SO(<Zeichenkette>)
<Zeichenkette>::=<a-z,A-Z>+

Abfrage von Spielinformationen

   
Spielfeld

Um Positionen auf dem Spielfeld eindeutig beschreiben zu können, wird das Spielfeld von seinem minimalen Rechteck umschlossen und dieses als weiterer Bezugsrahmen benutzt. Dieses Rechteck wird über zweidimensionale Koordinaten angesprochen, wobei (1,1) der südwestlichste Punkt und (ne,nn) der nordöstlichste ist. Die Größe des umschliessenden Rechtecks kann man direkt abfragen:


Info : <GibSFDim> $\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$<Ort>

<GibSFDim> ::= GSD
<Ort>::= (<N>,<N>)
Ebenso erhält man die Liste aller zu besuchenden Flaggen, wobei das erste Element der Liste die Startflagge ist.

Info : <GibFlaggen> $\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$<OrtLst>

<GibFlaggen> ::= GFL
<OrtLst> ::= <Ort>$^{\geq 2}$
Ein Spieler kann sich den gesamten Plan ausgeben lassen. Die nicht durch Kacheln abgedeckten Gebiete werden dann als Gruben (<Grube>) gekennzeichnet. Ansonsten ist der Plan analog zu den Spielfeldkacheln definiert. Auch hier werden zuerst die nördlichen Reihen ausgegeben.

Info : <GibPlan>$\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$<GesPlan>

<GibPlan>::= GPL
<GesPlan>::= <GPZwischenR><<GPFeldR><GPZwischenR>>+.
<GPZwischenR> ::= <Wand>+ <WS>
<GPFeldR>::= <Wand> <<BodenInhalt><Wand>>+<WS>

   
Spieler/Roboter

Die Namen aller Spieler lassen sich ebenfalls abfragen.


Info : <GibSpielerNamen>$\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$<NamenLst>

<GibSpielerNamen>::= GSN
<NamenLst>::= (<<Name>,>*)
<Name>::= <Zeichenkette>
Die Koordinaten eines nicht vom Spiel entfernten Roboters erhält man über den zugehörigen Spielernamen. Eine Anfrage auf einen entfernten Roboter gilt als Verletzung des Protokolls.

Info : <SucheRobOrt>$\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$<Ort>

<SucheRobOrt> ::= SRO(<Name>)
Den Inhalt eines Feldes mit seinen umgebenden Wänden, erhält man über dessen Ort. Zeigt der Ort auf einen Platz, der nicht durch eine Kachel abgedeckt ist, wird als Bodeninhalt <Grube> ohne begrenzende Wände zurückgegeben, es sei denn, der Ort grenzt an die Wand eines Kachelfelds. Die Wände werden durch ein Quadrupel wN wE wS wW beschrieben.

Info : <SucheFeldInhalt>$\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$<FeldBeschreibung>

<SucheFeldInhalt>::= SFI(<Ort>)
<FeldBeschreibung>::= (<BodenInhalt>,<Wand>4)
Auf den Zustand eines Roboters wird über seinen Namen zugegriffen. Zustände sind öffentlich. Ein Roboterzustand besteht aus Ist der Roboter aus dem aktiven Spiel entfernt worden, wird RSE zurückgegeben.

Info: <GibRobStatus>$\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$<RobStatus>

<GibRobStatus>::= GRS(<Name>)
<RobStatus>::= RS(<Richtung>,<Ort>,<LFlag>,<LArchF>,
<Schaden>, <VLeben>, <GespRegister>
<Aktiv>, <Virtuell>,<RSreserviert>) $\mid\ $
RSE 
<LFlag>::= <N>
<LArchF>::= <Ort>
<Schaden>::= 0$\mid\ $1$\mid\ $2$\mid\ $3$\mid\ $4$\mid\ $5$\mid\ $6$\mid\ $7$\mid\ $8$\mid\ $9$\mid\ $10
<VLeben>::= 0$\mid\ $1$\mid\ $2$\mid\ $3
<GespRegister>::= (<(<Register>,<ProgKarte>)>*)
<Register> ::= <Registerphase>
<Aktiv> ::= <Bool>
<Virtuell>::= <Bool>
<Bool>::= t $\mid\ $f
<RSreserviert> = $\varepsilon$
Eine Programmkarte definiert sich aus einer Aktion und der Priorität, mit der sie ausgeführt wird. Die Aktionen sind in der gleichen Art wie in der Beschreibung der Spielregeln bezeichnet. Dort sind auch die erlaubten Programmkarten definiert.

<ProgKarte>::= PK(<PKAktion>,<PKPriorität>)

<PKAktion>::= M1 $\mid\ $M2 $\mid\ $M3 $\mid\ $BU $\mid\ $RL $\mid\ $RR $\mid\ $UT
<PKPriorität>::= <N>

   
Spielstand

Das Spiel kann sich in zwei Zuständen befinden. Entweder es ist laufend (LAU) und es werden Spielzüge ausgewertet oder es ist beendet (END). Im letzteren Fall wird die Gewinnreihenfolge zurückgegeben. Dabei ist der erste Name in der Liste der Name des Gewinners.


Info:<GibSpSta> $\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$
<SpSta>

<GibSpSta>::= GSS
<SpSta>::= SS(LAU) $\mid\ $SS(END,<<Name>,>+)
Der aktuelle Spielauswertungsstatus besteht aus der aktuellen Registerphasen und den Programmkarten, die von den einzelnen Spielern schon ausgespielt wurden. Dabei bezeichnet die erste Programmkarte in der Liste die in Registerphase 1 gespielte Karte usw. Falls sich das Spiel in keiner Registerauswertungsphase befindet, wird keine Information zurückgegeben.

Info: <GibSpAusSta> $\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$
<SpAusStat>

<GibSpAusSta>::= GSA
<SpAusStat> ::= SA(<Registerphase>, <(<Name>, <ProgKarte>+)>+) $\mid\ $
SA()
 

   
Sonstiges

Bei der Zugabgabe gibt es einen Timeout. Die Größe des Timeouts in Sekunden kann abgefragt werden. Das Maximum beträgt 216-1 Sekunden.


Info: <GibTimeOut> $\mbox{\it\footnotesize sa} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize v}}$
<TimeOut> 
<GibTimeOut>::= GTO
<TimeOut> ::= TO(<Int>)
<Int>::= 0 ...(216-1)

Zugabgabe

Registerprogrammierung

Für die Zugabgabe der Registerprogrammierung werden bei einem neuen Zug neue Programmkarten ausgeteilt, wobei hinsichtlich ihrer Anzahl die Beschädigungen mitberücksichtigt werden.


Zugabgabe: <MkRegProgMv>$\mbox{\it\footnotesize v} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize s}}$<TkRegProgMv>

<MkRegProgMv>::= MRP(<ProgKarte>*)
Bei der entsprechenden Zugannahme wird eine Liste von Indizes ( $\in {\cal N}^+$) zurückgegeben, die sich auf die ausgeteilten Programmkarten beziehen. Ein Index mit dem Wert 1 bezeichnet also die erste Programmkarte in der bei der Zugabgabe übergebenen Liste. Für gesperrte Register wird kein Index zurückgegeben. Sind z.B. die Register 1,3,5 gesperrt, bedeutet eine Liste {4,1} bei der Zugannahme, daß Register 2 mit der vierten Programmkarte und Register 4 mit der ersten Programmkarte belegt wird.
Außerdem kann sich der Spieler entscheiden, ob er seinen Roboter im nächsten Zug deaktivieren möchte (Deaktivierung wird mit t gekennzeichnet, sonst f). Der Spieler weist sich durch seinen Namen aus. Die Zulässigkeit des Zugs wird vor der Ausführung überprüft. Wer schummelt, wird sofort aus dem Spiel ausgeschlossen.

<TkRegProgMv>::= TRP(<Name>,(<<N>,>*),<Deaktivierung>)

<Deaktivierung>::=<Bool>

Neuer Roboter

Nach dem Spielstart oder im Falle einer Zerstörung des Roboters, wird ebenfalls ein Zug verlangt.

Zugabgabe: <MkNeuerRob>$\mbox{\it\footnotesize v} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize s}}$<TkNeuerRob>

<MkNeuerRob>::=MNR
Der Spieler kann sich dabei für eine beliebige Ausrichtung entscheiden.

<TkNeuerRob>::= TNR(<Name>,<Richtung>)

Reaktivierung

War ein Roboter in einem Zug deaktiviert, wird er am Zugende gefragt, ob er deaktiviert bleiben möchte.

Zugabgabe: <MkBleibDeakt>$\mbox{\it\footnotesize v} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize s}}$<TkBleibDeakt>

<MkBleibDeakt>::= MBD
Möchte ein Roboter deaktiviert bleiben, gibt er ein t zurück ansonsten ein f.

<TkBleibDeakt>::= TBD(<Name>,<Bool>)

Reparatur

Wenn ein Roboter repariert wird, kann er die zu reparierenden Register unter den beschädigten frei wählen. Der Verwalter teilt ihm hierfür die Anzahl der zur Verfügung stehenden Reparaturpunkte mit. Die Aufforderung zur Wahl kommt seitens des Spielverwalters auch dann, wenn nur ein Register beschädigt ist. Sie kommt nicht, wenn keines beschädigt ist.

Zugabgabe: <MkRepRegWahl>$\mbox{\it\footnotesize v} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize s}}$<TkRepRegWahl>

<MkRepRegWahl>::= MRR(<N>)
<TkRepRegWahl>::= TRR(<Name>,<<Register>,>*)

Ausgabekanäle

Ausgabekanäle werden von Änderungen benachrichtigt, wobei alle Spielernamen, bei deren Robotern sich etwas geändert hat, übergeben werden. Ausgabekanäle signalisieren, wenn sie ihre Ausgabe beendet haben.


Änderungen: <NtfChange>$\mbox{\it\footnotesize v} \atop {\longleftrightarrow \atop \mbox{\it\footnotesize a}}$<OK>

<NtfChange>::= NTC(<<Name>,>*)
Ausgabekanäle erhalten mindestens eine Meldung bei den folgenden Ereignissen: Um proprietäre Ausgabekanäle zu ermöglichen, ignorieren Ausgabekanäle alle Nachrichten vom Verwalter, die sie nicht verstehen.

Interaktionsbeispiel

Im folgenden Bild kann man erkennen, wie eine Runde von zwei Spielern vom Verwalter zur Zugabgabe aufgefordert werden. Beide besorgen sich vor der Zugabgabe die hierfür nötigen Informationen. Wenn sie ihre Züge abgegeben haben, wird ein Ausgabekanal informiert. In diesem Beispiel wird bei den einzelnen Nachrichten nur der Kontext notiert und zwischen Anforderung (req) und Antwort (resp) unterschieden.

\epsfig{file=sequenceD.eps, width=\textwidth}

Änderungen

10.7.99

24.6.99 28.5.99 26.5.99 21.5.99 20.5.99 14.5.99 7.5.99


next up previous
Up: Anforderungen
Torsten Fink
1999-07-07