{"metadata":{"orig_nbformat":4,"celltoolbar":"Raw Cell Format","kernelspec":{"name":"python3","display_name":"Python 3 (ipykernel)","language":"python"},"language_info":{"name":"python","version":"3.7.10","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Software Entwicklung\n\n## Kapitel 11: Bots\n\n### 11.3 Bot-Client\n\n#### 11.3.1 Voraussetzung\n\nDas nachfolgende Beispielskript ist erst lauffähig, wenn der zugehörige Server läuft.","metadata":{}},{"cell_type":"markdown","source":"#### 11.3.2 Implementierung\n\nZunächst müssen dem Client die notwendigen Verbindungsdaten zur Verfügung gestellt werden.","metadata":{}},{"cell_type":"code","source":"host=\"127.0.0.11\" # IP-Nummer des Rechners, auf dem der Bot-Server läuft\nport=12345 # Hier muss die Portnummer eingetragen werden","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Der Server wird immer wieder den für den Bot sichtbaren Weltausschnitt als mehrzeiligen Text liefern.\nDer Ausschnitt ist immer quadratisch, d.h. aus der Länge der ersten Zeile lässt sich ableiten,\nwie viele Zeilen noch gelesen werden müssen. Die nachfolgende Funktion read_view\nleistet dieses Einlesen und gibt den sichtbaren Ausschnitt als String zurück.","metadata":{}},{"cell_type":"code","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","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Die Beispielimplementierung besitzt keine eigene Logik, sondern lässt nach Ausgabe des\nsichtbaren 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\nDie Funktion game_loop liefert dieses Verhalten.","metadata":{}},{"cell_type":"code","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","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Im Hauptprogramm muss schließlich eine Socket-Verbindung zum Server aufgebaut und\ndie game_loop gestartet werden.","metadata":{}},{"cell_type":"code","source":"import socket\n\nwith socket.socket() as s:\n s.connect((host, port))\n with s.makefile() as f:\n game_loop(f)\nprint(\"Client stopped.\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Viel Spass beim Trainieren!","metadata":{}}]}