|
|
@@ -1,160 +0,0 @@ |
|
|
|
{ |
|
|
|
"cells": [ |
|
|
|
{ |
|
|
|
"cell_type": "markdown", |
|
|
|
"metadata": {}, |
|
|
|
"source": [ |
|
|
|
"# Software Entwicklung\n", |
|
|
|
"\n", |
|
|
|
"## Kapitel 11: Bots\n", |
|
|
|
"\n", |
|
|
|
"### 11.3 Bot-Client\n", |
|
|
|
"\n", |
|
|
|
"#### 11.3.1 Voraussetzung\n", |
|
|
|
"\n", |
|
|
|
"Das nachfolgende Beispielskript ist erst lauffähig, wenn der zugehörige Server läuft." |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "markdown", |
|
|
|
"metadata": {}, |
|
|
|
"source": [ |
|
|
|
"#### 11.3.2 Implementierung\n", |
|
|
|
"\n", |
|
|
|
"Zunächst müssen dem Client die notwendigen Verbindungsdaten zur Verfügung gestellt werden." |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "code", |
|
|
|
"execution_count": null, |
|
|
|
"metadata": {}, |
|
|
|
"outputs": [], |
|
|
|
"source": [ |
|
|
|
"host=\"127.0.0.1\" # IP-Nummer des Rechners, auf dem der Bot-Server läuft\n", |
|
|
|
"port=12345 # Hier muss die Portnummer eingetragen werden" |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "markdown", |
|
|
|
"metadata": {}, |
|
|
|
"source": [ |
|
|
|
"Der Server wird immer wieder den für den Bot sichtbaren Weltausschnitt als mehrzeiligen Text liefern.\n", |
|
|
|
"Der Ausschnitt ist immer quadratisch, d.h. aus der Länge der ersten Zeile lässt sich ableiten,\n", |
|
|
|
"wie viele Zeilen noch gelesen werden müssen. Die nachfolgende Funktion <code>read_view</code>\n", |
|
|
|
"leistet dieses Einlesen und gibt den sichtbaren Ausschnitt als String zurück." |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "code", |
|
|
|
"execution_count": null, |
|
|
|
"metadata": {}, |
|
|
|
"outputs": [], |
|
|
|
"source": [ |
|
|
|
"def read_view(f):\n", |
|
|
|
" view = f.readline()\n", |
|
|
|
" if not view:\n", |
|
|
|
" return\n", |
|
|
|
" for x in range(2, len(view)):\n", |
|
|
|
" line = f.readline()\n", |
|
|
|
" if not line:\n", |
|
|
|
" return\n", |
|
|
|
" view += line\n", |
|
|
|
" return view" |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "markdown", |
|
|
|
"metadata": {}, |
|
|
|
"source": [ |
|
|
|
"Die Beispielimplementierung besitzt keine eigene Logik, sondern lässt nach Ausgabe des\n", |
|
|
|
"sichtbaren Ausschnitts die Steuerung des Bots über Tastatureingaben zu. Dabei bedeuten:\n", |
|
|
|
"\n", |
|
|
|
"* W -> Vorwärts\n", |
|
|
|
"* A -> Drehung nach links\n", |
|
|
|
"* D -> Drehung nach rechts\n", |
|
|
|
"* S -> Rückwärts\n", |
|
|
|
"* Jede andere Eingabe -> Beenden des Bots\n", |
|
|
|
"\n", |
|
|
|
"Die Funktion <code>game_loop</code> liefert dieses Verhalten." |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "code", |
|
|
|
"execution_count": null, |
|
|
|
"metadata": {}, |
|
|
|
"outputs": [], |
|
|
|
"source": [ |
|
|
|
"def game_loop(f):\n", |
|
|
|
" from IPython.display import clear_output\n", |
|
|
|
" \n", |
|
|
|
" commands = {'w':'^', 'a':'<', 's':'v', 'd':'>', 'W':'^', 'A':'<', 'S':'v', 'D':'>' }\n", |
|
|
|
"\n", |
|
|
|
" while True:\n", |
|
|
|
" try:\n", |
|
|
|
" view = read_view(f)\n", |
|
|
|
" if not view:\n", |
|
|
|
" break\n", |
|
|
|
" clear_output(wait=True)\n", |
|
|
|
" print(view)\n", |
|
|
|
" cmd = input(\"[WASD]:\")\n", |
|
|
|
" cmd = commands[cmd]\n", |
|
|
|
" s.send(str.encode(cmd))\n", |
|
|
|
" except Exception as e:\n", |
|
|
|
" print(e)\n", |
|
|
|
" break" |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "markdown", |
|
|
|
"metadata": {}, |
|
|
|
"source": [ |
|
|
|
"Im Hauptprogramm muss schließlich eine Socket-Verbindung zum Server aufgebaut und\n", |
|
|
|
"die <code>game_loop</code> gestartet werden." |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "code", |
|
|
|
"execution_count": null, |
|
|
|
"metadata": {}, |
|
|
|
"outputs": [], |
|
|
|
"source": [ |
|
|
|
"import socket\n", |
|
|
|
"\n", |
|
|
|
"with socket.socket() as s:\n", |
|
|
|
" s.connect((host, port))\n", |
|
|
|
" with s.makefile() as f:\n", |
|
|
|
" game_loop(f)\n", |
|
|
|
"print(\"Client stopped.\")" |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
"cell_type": "markdown", |
|
|
|
"metadata": {}, |
|
|
|
"source": [ |
|
|
|
"Viel Spass beim Trainieren!" |
|
|
|
] |
|
|
|
} |
|
|
|
], |
|
|
|
"metadata": { |
|
|
|
"celltoolbar": "Raw Cell Format", |
|
|
|
"kernelspec": { |
|
|
|
"display_name": "Python 3", |
|
|
|
"language": "python", |
|
|
|
"name": "python3" |
|
|
|
}, |
|
|
|
"language_info": { |
|
|
|
"codemirror_mode": { |
|
|
|
"name": "ipython", |
|
|
|
"version": 3 |
|
|
|
}, |
|
|
|
"file_extension": ".py", |
|
|
|
"mimetype": "text/x-python", |
|
|
|
"name": "python", |
|
|
|
"nbconvert_exporter": "python", |
|
|
|
"pygments_lexer": "ipython3", |
|
|
|
"version": "3.9.2" |
|
|
|
} |
|
|
|
}, |
|
|
|
"nbformat": 4, |
|
|
|
"nbformat_minor": 2 |
|
|
|
} |