SAI || Sommersemester 1997 || Systemnahe Software II || Übungen

Übungen zu Systemnahe Software II
Blatt 5 (02. 06. - 09. 06. 1997)


Aufgabe 6 (10 Punkte)

Bauen Sie Ihre Lösung von Aufgabe 3 oder das Lösungsbeispiel aus den Übungen -- /www/thales/ftp/pub/vorlesungen/ss97/soft/loesung/3.shar -- zu einem Klienten für den Gobang-Server aus, der auf Turing als /local/bin/gbs istalliert ist.

Dieser Server koordiniert eine Partie Gobang (Regeln siehe unten) zwischen zwei unabhängigen Klienten. Die Kommunikation findet über FIFO-Dateien (named pipes) statt. FIFO-Dateien funktionieren genau wie gewöhnliche Pipelines, haben aber einen Dateinamen, sodaß sich per open auch nicht miteinander verwandte Prozesse daran ankoppeln können. Mehr dazu in den Übungen oder in den Manualseiten zu mkfifo(3c) und mknod(2).

Aufgabe des Klienten ist es, das Spielbrett darzustellen und bei Bedarf einen Zug vom Spieler entgegenzunehmen und an den Server weiterzuleiten. Dieser übermittelt an alle Beteiligten die daraus resultierende Veränderung der Spielsituation und an einen bestimmten Klienten eine Aufforderung zur Zugabgabe. Die Kontrolle, welche Züge gültig sind und wer am Zug ist, obliegt somit ebenso wie die Feststellung des Spielendes und -ergebnisses dem Server.

Für verschiedenartige, aber ähnlich ablaufende Spiele wären weitere Server denkbar, die mit denselben Klienten zusammenarbeiten würden. Ferner eignet sich ein Klient auch dazu, eine fremde Partie lediglich zu beobachten (zu "kibitzen"), wenn der Server passive Teilnehmer zuläßt, die abgesehen von Eingabeaufforderungen dieselben Informationen erhalten wie die aktiven.

Pipelines als Kommunikationsmedium zwischen Klienten und Servern bieten wesentlich weniger Komfort als fortgeschrittenere Techniken, die später noch behandelt werden. Daher beschränkt sich dieses Beispiel auf eine relativ einfache "Netzwerk"-Struktur. Jeder beteiligte Prozess besitzt genau eine zum Lesen geöffnete FIFO. In diejenige des Servers schreiben abwechselnd alle Klienten, in die der Klienten dagegen nur der Server. Es wird davon ausgegangen, daß jeder Prozess normalerweise Daten in seiner FIFO erwartet und liest, sodaß auf der schreibenden Seite nicht mit Blockieren zu rechnen ist. Die einzige Ausnahme bildet der Klient, an den gerade eine Aufforderung zur Zugabgabe ergangen ist; er darf weitere Nachrichten ignorieren, bis er eine Reaktion seines Benutzers vom Terminal eingelesen und weitergegeben hat.

Klienten und Server sind Prozesse auf derselben Maschine (Turing). Damit sie leicht miteinander in Kontakt treten können, benutzen sie FIFO-Dateinamen nach einem vorgegebenen Muster:
/tmp/gbs.nnnnn für Nachrichten an den Server,
/tmp/gbc.nnnnn für Nachrichten an einen Klienten,

wobei nnnnn die gegebenenfalls mit führenden Nullen versehene Prozeßnummer (pid) des zugehörigen Prozesses ist. Jeder Prozess erzeugt die FIFO, in der er Nachrichten empfangen möchte, und entfernt den entsprechenden Dateinamen auch wieder, sobald er nicht mehr gebraucht wird. Das ist bei Klienten der Fall, sobald der Server zum ersten Mal geantwortet hat. Der Server entfernt seine FIFO aus dem Dateibaum, bevor er terminiert.

Eine typische Sitzung für eine Partie Gobang könnte wie folgt aussehen:

% gbs 11 &
[1]     17223
% my_client -b 17223
Playing the black stones.
Trying to contact server #17223 ...
Connection established, board size = 11.
Waiting for your partner to sign on ...

(Spiel ...)

Game over!
% 

Da alle Nachrichten an den Server über dieselbe FIFO laufen, haben sie ein einheitliches kurzes Format:
pid opcode x y
16 bit 4 bit 6 bit 6 bit

Die Prozeßnummer des Absenders muß immer korrekt sein, da der Server aus ihr auf die Herkunft der Nachricht und auf den FIFO-Dateinamen des Klienten schließt. Die Koordinaten x und y werden nur in bestimmten Fällen bewertet und können ansonsten auf Null gesetzt werden. Folgende Opcodes sind implementiert:
Code Bedeutung
0 Signoff = kontrolliertes Beenden der Verbindung
1 Signon (black) = Spielbeginn mit schwarzen Steinen
2 Signon (white) = Spielbeginn mit weißen Steinen
3 Signon (kibitz) = Anmelden als Zuschauer
4 Move x, y = Zug auf Feld x, y;
  x = y = 0 bedeutet Verzicht auf einen Zug (Pass)
8 Resign = Vorzeitige Spielbeendigung als Verlierer
15 Kill = Abschießen des Servers

Der Kibitz-Modus muß für diese Übungsaufgabe nicht implementiert werden. Nachrichten an Klienten folgen demselben Format für Opcodes und Argumente, es fehlt allerdings die Prozeßnummer. Folgende Opcodes sollen erkannt werden:
Code Bedeutung
0 Spielende, unentschieden
1 Spielende, Schwarz gewinnt
2 Spielende, Weiß gewinnt
3 vorzeitiges unerwartetes Spielende
4 Entferne Stein von Position x, y (kommt im konkreten Spiel nicht vor)
5 Setze schwarzen Stein auf Position x, y
6 Setze weißen Stein auf Position x, y
7 Spielfeldgröße ist y (erste Antwort auf Signon-Nachricht)
8 Aufforderung zur Zugabgabe
9 Information: Zug wäre illegal (danach folgt erneut Opcode 8)

Die Regeln für die hier realisierte Gobang-Variante sind die folgenden:

Gobang ist ein Brettspiel für zwei Spieler. Ein Spieler spielt mit schwarzen, der andere mit weißen Steinen.

Begonnen wird mit einem leeren Brett der Größe 11x11 (Voreinstellung) oder einer zu wählenden Größe.

Die Spieler setzen abwechselnd einen Stein ihrer Farbe auf ein noch unbesetztes Spielfeld. Der erste Zug steht dem Spieler mit den schwarzen Steinen zu.

Das Spiel ist beendet, sobald ein Spieler mindestens fünf eigene Steine in einer lückenlosen geraden Linie auf dem Brett plazieren konnte. Gültig sind waagrecht, senkrecht oder diagonal verlaufende Reihen von Steinen. Der Spieler, der eine solche Reihe legen konnte, gewinnt.

Das Spiel endet unentschieden, wenn nirgendwo auf dem Brett mehr Platz zur Vervollständigung einer Fünferreihe ist. Eine äquivalente Abbruchbedingung wäre, daß überhaupt kein Feld mehr frei ist, aber dies würde Spiele mit bereits feststehendem Ergebnis nur unnötig verlängern.

Jederzeit darf auf einen Zug verzichtet werden. Wenn beide Spieler nacheinander verzichten, endet das Spiel ebenfalls unentschieden.

Ein Spieler, der am Zug ist, kann die Partie auch aufgeben. Sie endet dann zugunsten des anderen Spielers.

Beispiel für eine siegreich von Weiß (Symbol: O) beendete Partie:
                     
                     
                O    
              X      
            X        
          X X X      
    X X X O O        
    X O O O X        
      O O            
    O O X O          
  O X                


SAI || Sommersemester 1997 || Systemnahe Software II || Übungen

Martin Hasch, Juni 1997