Projekt:2021/WORDLE: Unterschied zwischen den Versionen

Aus Informatik-Box
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
Markierung: Manuelle Zurücksetzung
 
Zeile 20: Zeile 20:
* Malin, Enno
* Malin, Enno
* Hung, Jan
* Hung, Jan
* Maxim, Oliver, Artem
* Maxim, <del>Oliver</del>, Artem


=== Links ===
=== Links ===

Aktuelle Version vom 27. März 2022, 21:29 Uhr

Seite zum Projekt Wordle des Informatik LK im Schuljahr 2021/22.

Projekt Wordle

Icon Heft.png
Arbeitsauftrag

Modelliert und implementiert zu zweit einen Wordle Server, der das im Unterricht entwickelte WOPP3 vollständig umsetzt.

  1. Modelliert das Server-Programm, indem ihr gemeinsam ein Implementierungsdiagramm für das Projekt erstellt. Modelliert auch die wichtigsten Abläufe des Spiels als Sequenzdiagramme (Anmeldung, WOTD spielen, ein Spiel pausieren/fortsetzen, ...). Speichert die UML-Dateien im Projektordner im Unterordner modell.
  2. Modelliert ein Datenbankschema für die Umsetzung des Spiels.
  3. Implementiert den Wordle-Server so, dass das vereinbarte Protokoll möglichst exakt umgesetzt wird. Beachtet die Hinweise unten auf dieser Seite.

Gruppen

  • Maja, Simon
  • Alperen, Tim
  • Malin, Enno
  • Hung, Jan
  • Maxim, Oliver, Artem

Links

Das WORDLE Play Protocol 3 (WOPP3)

Positiver Indikator: +OK
Negativer Indikator: -ERR
Antwort auf nicht gültige Befehle: -ERR command not valid in this state

Immer möglich: 
QUIT
						+OK bye


- Client baut Verbindung auf -
						+OK <willkommensnachricht>

## Anmeldephase

USER <username>
						+OK
						-ERR <nachricht>
PASS <password>
						+OK welcome
						-ERR login not valid
WOTD
						+OK game ready | game running
						-ERR game finished
PLAY
						+OK game ready | game running
						-ERR not logged in | wotd not finished

## Spielphase

SEND <wordl>
						+OK <answer>
						game continues | game won | game lost
							Five chars with:
								0 = not in word
								1 = wrong place
								2 = correct
						-ERR wrong format | word not in dict 
INFO
						+OK
						wort1 01002
						wort2 01012
						wort3 02100
						.
INFO <n>
						+OK wortN 01020
EXIT						
						+OK
						Wechsel in Zwischenphase
						-ERR not logged in

## Zwischenphase (angemeldet)

STAT 
						+OK 
						times played: <int>
						win percentage: <int>
						current streak: <int>
						max streak: <int>
						won in 1 turn: <int>
						won in 2 turn: <int>
						won in 3 turn: <int>
						won in 4 turn: <int>
						won in 5 turn: <int>
						won in 6 turn: <int>
						.
PLAY
						+OK game ready | game running
						-ERR wotd not finished

Hinweise zur Umsetzung

Nicht-blockierende Verbindungen

Jede Verbindung eines Clients zum Server erzeugt einen neuen Thread, der für die Kommunikation mit diesem Client zuständig ist. Um über eine spezifische Verbindung eine Nachricht zu empfangen, müssen daher die IP und Portnummer der Verbindung angegeben werden. Diese werden als Parameter immer einer der Methoden übergeben, die für die Verarbeitung von eingehenden Nachrichten zuständig sind. Sobald eine Nachricht eintrifft, sorgt die Server-Klasse dafür, dass die entsprechende process* Methode aufgerufen wird.

Wird etwa eine neue Verbindung von einem Client aufgebaut, dann wird processNewConnection(String pClientIP, int pClientPort) aufgerufen. Hier könnte der Server dann eine Antwort an den Client senden:

@Override
public void processNewConnection( String pClientIP, int pClientPort ) {
    // Verarbeite die neue Verbindung (z.B. letzten Spielstand wiederherstellen, ...)
    send(pClientIP, pClientPort, "+OK welcome to wordle");
}

Verbindungsspezifische Daten speichern

Der Server muss Daten pro Client speichern können (z.B. Spielstände). Clients können anhand der IP plus Portnummer identifiziert werden. Es müssen also abhängig von einem Schlüssel (IP+Port) Werte gespeichert werden. Eine Datenstruktur, die das erlaubt, kennen wir schon: Hashtabellen.

Datenpersistenz

Damit der Server Daten auch nach einem Verbindungsabbruch wiederherstellen kann, muss er sie dauerhaft speichern. Dazu können wir die Datenbank nutzen, um die Zustände abhängig von IP und Portnummer abzulegen.

Dokumentationen

Die Projektvorlage enthält die nötigen Abiturklassen und eine Datenbank mit einer Reihe von deutschen Wörtern mit fünf Buchstaben. Die Datenbank kann um weitere Tabellen eures erstellten Schemas ergänzt werden.

Tabelle words
id word
1 Abbau
2 Abend
... ...

Die Klasse Server

Über die Klasse Server ist es möglich, eigene Serverdienste anzubieten, so dass Clients Verbindungen gemäß dem TCP/IP-Protokoll hierzu aufbauen können. Nachrichten werden grundsätzlich zeilenweise verarbeitet, d. h., beim Senden einer Zeichenkette wird ein Zeilentrenner ergänzt und beim Empfangen wird er entfernt.

Verbindungsaufbau, Nachrichtenempfang und Verbindungsende geschehen nebenläufig. Durch Überschreiben der entsprechenden Methoden kann der Server auf diese Ereignisse reagieren.

Eine Fehlerbehandlung ist in dieser Klasse aus Gründen der Vereinfachung nicht vorgesehen.

Server(int pPortNr)
Nach dem Aufruf dieses Konstruktors bietet ein Server seinen Dienst über die angegebene Portnummer an. Clients können sich nun mit dem Server verbinden.

void closeConnection(String pClientIP, int pClientPort)
Unter der Voraussetzung, dass eine Verbindung mit dem angegebenen Client existiert, wird diese beendet. Der Server sendet sich die Nachricht processClosedConnection.

void processClosedConnection(String pClientIP, int pClientPort)
Diese Methode ohne Anweisungen wird aufgerufen, bevor der Server die Verbindung zu dem in der Parameterliste spezifizierten Client schließt. Durch das Überschreiben in Unterklassen kann auf die Schließung der Verbindung zum angegebenen Client reagiert werden.

void processMessage(String pClientIP, int pClientPort, String pMessage)
Der Client mit der angegebenen IP und der angegebenen Portnummer hat dem Server eine Nachricht gesendet. Dieser ruft daraufhin diese Methode ohne Anweisungen auf. Durch das Überschreiben in Unterklassen kann auf diese Nachricht des angegebenen Client reagiert werden.

void processNewConnection(String pClientIP, int pClientPort)
Der Client mit der angegebenen IP-Adresse und der angegebenen Portnummer hat eine Verbindung zum Server aufgebaut. Der Server hat daraufhin diese Methode aufgerufen, die in dieser Klasse keine Anweisungen enthält. Durch das Überschreiben in Unterklassen kann auf diesen Neuaufbau einer Verbindung von dem angegebenen Client zum Server reagiert werden.

void send(String pClientIP, int pClientPort, String pMessage)
Wenn eine Verbindung zum angegebenen Client besteht, dann wird diesem Client die angegebene Nachricht - um einen Zeilentrenner erweitert - gesendet.

void sendToAll(String pMessage)
Die angegebene Nachricht wird - um einen Zeilentrenner erweitert - an alle verbundenen Clients gesendet.

void close()
Alle bestehenden Verbindungen werden getrennt. Der Server kann nicht mehr verwendet werden.