Dies ist eine alte Version des Dokuments!
Der Agent
Um das Programmieren mit Python in Minecraft Education einfacher zu erlernen, steht jedem Lernenden neben der Spielfigur, welche die Position des Spielers samt Inventar und Handlung im Spiel darstellt, auch ein sogenannter Agent zur Verfügung. Der Agent selbst kann durch Programmieren gesteuert werden. Dafür gibt es verschiedene Befehle. Jeder Spieler hat nur einen Agenten und das Gute ist, Agenten können nicht verschwinden («sterben»)!
Wir können den Agenten mit Hilfe von Befehlen/Programmen steuern und so dafür sorgen, dass er Arbeiten für uns erledigt. Er kann beispielsweise Dinge für uns bauen, oder Gegenstände einsammeln etc.
Sobald man mit der Taste C den Code-Editor zum Programmieren öffnet, erscheint in der Minecraft-Welt der Agent. Es handelt sich um einen kleinen Roboter bzw. um eine kleine Spielfigur, die man mit den Agent-Befehlen steuern kann. Der Agent ist genau ein Block hoch. Einige der Befehle für den Agenten sind samt Kommentar und einem Beispiel unten aufgelistet.
Damit der Agent bauen kann, muss sein Inventar befüllt werden. Dieses Inventar des Agenten ist separat vom Spieler und kann per Rechtsklick auf den Agenten eingesehen und verändert werden. Man kann es auch durch Programmierung und den Befehl agent.set_item verändern (siehe weiter unten).
Aufgaben
Allgemeiner Auftrag:
Probiert in mindestens drei verschiedenen Beispielen die unten aufgelisteten Befehle aus und lasst den Agenten bewegen und bauen. Dazu könnt ihr Euch auch in Zweiergruppen gegenseitig kleine Aufgaben stellen, die der Agent ausführen soll. Tipp: Beginnt mit einer sehr einfachen Aufgabe und stellt Euch dann langsam den grösseren Herausforderungen.
Aufgabe 1
Betrachte das untenstehende Programm und überlege dir, was es macht. Kopiere es in Minecraft und teste es ('c' drücken und dann in „Python“ einfügen).
# Grundeinstellungen agent.set_assist(PLACE_ON_MOVE, True) agent.set_item(GOLD_BLOCK, 64, 1) agent.set_slot(1) # Programm agent.move(FORWARD,5) agent.turn_left() agent.move(FORWARD,5) agent.turn_left() agent.move(FORWARD,5) agent.turn_left() agent.move(FORWARD,5)
Aufgabe 2
Ich möchte, dass der Agent ein Quadrat der Seitenlänge 5 baut, doch irgendetwas funktioniert nicht?
Versuche das Programm so zu ändern, dass er wirklich ein Quadrat der Seitenlänge 5 baut.
Aufgabe 3
Füge deinem Programm eine Variable mit dem Namen Seitenlaenge hinzu, sodass du über diese Variable steuern kannst, wie gross dein Quadrat wird.
Aufgabe 4
Erkläre, was der Agent baut, wenn das untenstehende Programm ausgeführt wird. Erstelle eine Skizze.
agent.set_assist(PLACE_ON_MOVE, True)
agent.set_item(GOLD_BLOCK, 64, 1)
agent.set_item(GRASS, 64, 2)
agent.set_item(DIAMOND_BLOCK, 64, 3)
distances = [4,6,2]
for i in range(1,4):
agent.set_slot(i)
agent.place(LEFT)
agent.move(FORWARD, distances[i-1])
Welche Erkenntnisse sollen gewonnen werden?
- Wie kann ich den Agenten durch ein Pyhtonprogramm bewegen?
- Wie kann ich den Agenten etwas bauen lassen und was ist dabei zu beachten?
- Was muss beim Programmieren des Agenten in bezug auf folgende Aspekte beachtet werden:
- Was muss beim Verwenden von Kooridnaten beachtet werden?
- Was muss beim Befüllen des Inventars des Agenten beachtet werden?
- Welche Voreinstellungen in den ersten Codezeilen sind nützlich?
- Welche Programmierfehler sind passiert, und warum sind diese passiert!
</WRAP>
Einige Agentenbefehle im Überblick
Den Agenten bewegen
Um den Agenten zu bewegen, gibt es einige einfache Befehle, die sehr nützlich sind.
| Befehl | Beispiel | Kurzerklärung |
|---|---|---|
agent.move(Richtung, Anz.Felder) | agent.move(BACK,3) | Agent bewegt sich um die Anzahl Felder in die gewünschte Richtung (FORWARD, BACK, LEFT, RIGHT, UP, DOWN) |
agent.turn(Richtung) | agent.turn(LEFT) | Agent dreht sich um 90 Grad in die gewünschte Richtung (LEFT, RIGHT) |
| Den Agenten teleportieren | ||
agent.teleport(Position, Himmelsrichtung) | agent.teleport(pos(10,5,2),WEST) | pos teleportiert bezüglich der Position des Agenten |
agent.teleport(world(3,10,5), NORD) | world | teleportiert absolut bezüglich der Weltkoordinaten |
agent.teleport_to_player() | Der Agent wird an die Position des Spielers teleportiert, d.h. der Agent wird, egal wo er ist, zum Spieler versetzt, ohne dabei den Raum zu durchqueren. | |
Bemerkung: Wenn von einer Richtung die Rede ist, kann meist zwischen FORWARD, BACK, LEFT, RIGHT, UP, DOWN gewählt werden. Im Zusammenhang mit Himmelsrichtung dann EAST, WEST, NORTH, SOUTH.Bemerkung: Wenn von einer Richtung die Rede ist, kann meist zwischen FORWARD, BACK, LEFT, RIGHT, UP, DOWN gewählt werden. Im Zusammenhang mit Himmelsrichtung dann EAST, WEST, NORTH, SOUTH.
Das Inventar des Agenten
Wie bereits genannt, kann das Inventar des Agenten manuell über den Rechtsklick und das Inventar des Spielers aufgefüllt werden. Es kann aber auch über die Funktion agent.set_item ein auffüllen vom Inventar vorgenommen werden. Erinnerung: Der Agent kann nur bauen, wenn das Inventar nicht leer ist! ein auffüllen vom Inventar vorgenommen werden. Erinnerung: Der Agent kann nur bauen, wenn das Inventar nicht leer ist!
| Befehl | Beispiel | Kurzerklärung |
|---|---|---|
agent.set_item(Material, Anzahl, Slot) | agent.set_item(GRASS, 6, 1) | 6 Grasblöcke in den ersten Slot des Inventars legen. |
agent.drop_all(Richtung) | agent.drop_all(FORWARD) | Das ganze Agenten-Inventar kann auch wieder geleert werden, um so eventuell neu befüllt zu werden. Dies geschieht über die Funktion agent.drop_all(Richtung). Die Blöcke werden dann in der angegebenen Richtung neben dem Agenten sichtbar schweben und verschwinden nach einiger Zeit, falls diese nicht eingesammelt werden. Im Beispiel wird hier das Inventar so geleert, dass die gesamten Materialien vor dem Agenten liegen. |
agent.transfer(Von Slot, zu Slot, Anzahl) | agent.transfer(5, 1, 2) | Das Agenten-Inventar kann auch umgeordnet werden, indem Materialien von einem Slot in einen anderen gelegt werden. |
Der Agent baut und arbeitet für uns
Neben dem Bewegen kann der Agent auch für uns bauen. Auch hier gibt es einige praktische Grundbefehle.Neben dem Bewegen kann der Agent auch für uns bauen. Auch hier gibt es einige praktische Grundbefehle.
| Befehl | Beispiel | Kurzerklärung |
|---|---|---|
agent.place(Richtung) | agent.place(FORWARD) | Der Agent plaziert vor sich einen Block. Er nimmt das Material immer aus dem aktiven Slot. Falls dies nicht der gewünschte Slot ist, kann durch agent.set_slot(Slotnummer) dieser gewechselt werden. |
agent.set_slot(Slotnummer) | agent.set_slot(2) | Der aktive Slot wird gewählt, aus dem dann das Material genommen wird. |
agent.set_assist(assist, on-off) | agent.set_assist(PLACE_ON_MOVE,True) | Setzt man PLACE_ON_MOVE auf wahr (True), dann baut der Agent während er sich bewegt. |
agent.set_assist(assist, on-off) | agent.set_assist(DESTROY_OBSTACLES,True) | Setzt man DESTROY_OBSTACLES auf wahr (True), dann zerstört er die Hindernissse, während er baut. |
Der Parameter assist kann folgende Werte annehmen:Der Parameter assist kann folgende Werte annehmen:
PLACE_ON_MOVEwas bedeutet, dass der Agent mit jeder Bewegung baut.PLACE_FROM_ANY_SLOTheisst, wenn der aktive Inventarslot kein Material beinhaltet, wird das gesamte Inventar durchsucht und so zu einem gefüllten Slot wechseln und weiterfahren.DESTROY_OBSTACLESwird gebraucht, um zu vermeiden, dass der Agent durch Hindernisse blockiert wird. Der Agent kann durch Blöcke, Tiere oder anderes blockiert sein und nicht vorwärts kommen. Durch diese Funktion und diesen Parameter kann ddas Hindernis aus dem Weg geräumt, sprich zerstört werden.
Der Parameter on-off kann folgede Werte annehmen:Der Parameter on-off kann folgede Werte annehmen:
True, dadurch ist die Funktino agent.set_assist aktiviert.False, durch diesen Parameterwert wird die Funktion deaktiviert.
Der Agent wird mit diesem Befehl bei jeder Bewegung bauen. Im gegebenen Beispiel oben baut der Agent bei jeder Bewegung einen Block aus den aktiven Slot.Der Agent wird mit diesem Befehl bei jeder Bewegung bauen. Im gegebenen Beispiel oben baut der Agent bei jeder Bewegung einen Block aus den aktiven Slot.
Ein Beispiel wäre das Folgende. Hier wird der Agent zuerst einen GRASS-Block in sein Inventar in Slot 1 nehmen, sich danach um 4 Felder vorwärts bewegen, anschliessend einen Block vor sich hin setzen, nach links drehen und von sich aus gesehen 5 Felder rückwärts bewegen.Ein Beispiel wäre das Folgende. Hier wird der Agent zuerst einen GRASS-Block in sein Inventar in Slot 1 nehmen, sich danach um 4 Felder vorwärts bewegen, anschliessend einen Block vor sich hin setzen, nach links drehen und von sich aus gesehen 5 Felder rückwärts bewegen.
agent.set_item(GRASS, 5, 1) agent.move(FORWARD,4) agent.place(FORWARD) agent.turn_left() agent.move(BACK,5)
Durch ein Rechtsklick auf den Agenten ist klar, dass es noch 4 GRASS-Blöcke in Slot 1 hat. Einer wurde ja begraucht.Durch ein Rechtsklick auf den Agenten ist klar, dass es noch 4 GRASS-Blöcke in Slot 1 hat. Einer wurde ja begraucht.
Programmierkonzepte in Python
1. Variablen verwenden
meinKoffer = 3
Es wurde eine Variable mit dem Namen meinKoffer erstellt und darin der Wert 3 abgelegt. Jedes Mal, wenn nun die Variable im Programm aufgerufen wird, wird sie durch ihren aktuellen Wert ersetzt.
In manchen Programmiersprachen muss man bei jeder Variable angeben, welcher Typ von Daten gespeichert werden soll (damit im Speicher des Computers die richtige Menge Platz reserviert werden kann), dies ist in Python nicht der Fall. In derselben Variable kann man eine Ganze Zahl, eine Kommazahl, einen Text, eine Liste etc. speichern. Man muss einfach den „alten“ Wert durch einen neuen Wert überschreiben:
# Verschidene Datentypen können in derselben Variablen gespeichert werden a = 1 print(a+1) a = "Ein Text" a = True
Im obigen Beispiel werden der Variablen a verschiedene Werte zugewiesen:
- Zuerst erhält sie den Wert 1, eine natürliche Zahl, ein sogenannter Integer (kurz int).
- Dann wird in der Variablen zwei Zeilen später ein sog. string ein Stück Text gepeichert. Mit dieser Variable könnte man jetzt nicht mehr rechnen, da darin keine Zahl mehr gepeichert wird.
- Und schliesslich in der letzten Zeile wird der Variablen „True“ (boolean) zugewiesen, einer der beiden Wahrheitswerte
TrueoderFalse.
Aufgabe B
- Analysiere das untenstehende Programm. Was macht der Agent?
- Welche Variablen beinhaltet das Programm? Identifiziere diese Variablen. (Bemerkung: wir werden weiter später sehen, wie man dieses Beispiel viel eleganter programmieren kann.)
- Erweitere das Programm wie folgt:
- Während des Programmablaufs nehmen bereits vorhandene Variablen einen anderen Wert an.
- Eine weitere Variable wird eingeführt und vom Programm auch genutzt.
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen schrittgroesse = 4 ausrichtung = WEST xKoord = 1 yKoord = 1 zKoord = 1 agent.teleport(pos(xKoord,yKoord,zKoord),ausrichtung) agent.move(FORWARD,schrittgroesse) agent.teleport(pos(xKoord+1,yKoord+1,zKoord+1),ausrichtung) agent.move(FORWARD,schrittgroesse)
mögliche Lösungen
Aufgabe 3a
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen schrittgroesse = 4 ausrichtung = WEST xKoord = 1 yKoord = 1 zKoord = 1 agent.teleport(pos(xKoord,yKoord,zKoord),ausrichtung) agent.move(FORWARD,schrittgroesse) schrittgroesse = 6 # Beispielsweise hier die Schrittgrösse auf 6 setzen. agent.teleport(pos(xKoord+1,yKoord+1,zKoord+1),ausrichtung) agent.move(FORWARD,schrittgroesse)
Aufgabe 3b
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen schrittgroesse = 4 ausrichtung = WEST bewegungserichtung = FORWARD xKoord = 1 yKoord = 1 zKoord = 1 bewegungsrichtung = FORWARD # Beispielsweise hier eine Bewegungsrichtung definieren. agent.teleport(pos(xKoord,yKoord,zKoord),ausrichtung) agent.move(bewegungsrichtung,schrittgroesse) schrittgroesse = 6 # Beispielsweise hier die Schrittgrösse auf 6 setzen. agent.teleport(pos(xKoord+1,yKoord+1,zKoord+1),ausrichtung) agent.move(bewegungsrichtung,schrittgroesse)
Namen für Variablen und Funktionen
Wichtige Variablen oder Funktionen sollten (wenn möglich) Namen haben, die ihre Bedeutung erkennen lassen. Es gibt zwei Konventionen, die sich bei Namen mit mehreren Wörter etabliert haben:
| Camelcase (Kamelfall) | Bei Namen, die aus mehreren Wörtern bestehen, wird jeweils bei einem neuen Wort der erste Buchstabe grossgeschrieben. Der allererste Buchstabe jedoch klein (Bsp: anzahlGoldbloecke, rechtesFenster). |
| Snakecase (Schlangenfall) | Bei Namen, die aus mehreren Wörtern bestehen, werden diese durch einen Unterstrich getrennt (Bsp. anzahl_goldbloecke, rechtes_fenster) |
Was bringen diese Variablen?
Stelle dir vor, du hast ein kleines Programm geschrieben, welches den Agenten dazu bringt, eine Spirale zu bauen (wir werden weiter später sehen, wie man das Beispiel eleganter programmieren kann):
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen agent.move(FORWARD,1) agent.turn(LEFT) agent.move(FORWARD,2) agent.turn(LEFT) agent.move(FORWARD,3) agent.turn(LEFT) agent.move(FORWARD,4) agent.turn(LEFT) agent.move(FORWARD,5) agent.turn(LEFT) agent.move(FORWARD,6)
Wie du siehst, wird sehr häufig der Befehl agent.turn(LEFT) verwendet. Wenn du nun dein Programm leicht verändern möchtest, so dass der Agent die Spirale nach rechts machen soll, statt nach links, musst du all diese agent.turn(LEFT)-Befehle zu agent.turn(RIGHT) ändern, was bei grösseren Programmen sehr mühsam sein kann. Es ist besser, die Drehrichtung in einer Variablen zu speichern und im Code dann diese Variable zu verwenden. Dadurch muss nur der Wert der Variablen geändert werden, um die Spirale in die andere Richtung drehen zu lassen.
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen drehRichtung = LEFT # Alternativ: drehRichtung = RIGHT agent.move(FORWARD,1) agent.turn(drehRichtung) agent.move(FORWARD,2) agent.turn(drehRichtung) agent.move(FORWARD,3) agent.turn(drehRichtung) agent.move(FORWARD,4) agent.turn(drehRichtung) agent.move(FORWARD,5) agent.turn(drehRichtung) agent.move(FORWARD,6)
Zusammenfassend lässt sich sagen, dass durch Variablen die Programme (oder Arbeitsabläufe des Agenten in diesem Beispiel) flexiebler einsetzbar und besser anpassbar werden.
2. Eigene Funktionen definieren mit ''def''
agent.place(FORWARD) ..
Oft hilft es auch, eigene Funktionen zu programmieren. Der Vorteil liegt auf der Hand: wenn mehrmals dieselben Anweisungen nacheinander ausgeführt werden sollen, kann man diese als Funktion speichern und diese Funktion dann mehrmals über ihren Namen aufrufen.
Dies wird in Python durch den Befehl def realisiert. Dadurch wird das Programm oft kürzer und übersichtlicher.
Wir können beispielsweise unser Spiralbeispiel als Funktion definieren, und dann viele Spiralen bauen, weil wir die definierte Funktion beliebig oft aufrufen können:
- baueSpirale.py
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen def baueSpirale(): drehRichtung = LEFT # Alternativ: drehRichtung = RIGHT agent.move(FORWARD,1) agent.turn(drehRichtung) agent.move(FORWARD,2) agent.turn(drehRichtung) agent.move(FORWARD,3) agent.turn(drehRichtung) agent.move(FORWARD,4) agent.turn(drehRichtung) agent.move(FORWARD,5) agent.turn(drehRichtung) agent.move(FORWARD,6) baueSpirale() agent.move(FORWARD, 10) baueSpirale() agent.move(FORWARD, 10) baueSpirale() agent.move(FORWARD, 10) baueSpirale() agent.move(FORWARD, 10)
Aufgaben C
- Überlege dir, was der Agent genau baut, wenn man das oben angegebene Programm ausführt. Bei welcher Zeile des Codes beginnt der Agent mit dem Bauen?
- Mache eine kleine Skizze: wie wird das gebaute Objekt wohl aussehen? Häuschenpapier kann viel helfen…
- Überprüfe deine Überlegung und deine Skizze, indem du das Programm in Minecraft einfügst und ausführst (evt. musst du zunächst den Agenten zu dir teleportieren. Im Chat kannst du das machen mit
/teleport @c @s)
- Gibt es eine Möglichkeit, das in vorige Aufgabe (Aufgabe 3) geschriebene Programm zu verkürzen? Wenn ja, welche? Wenn nein, warum bist du sicher, den kürzesten Programmcode gefunden zu haben?
- Schreibe eine Funktion
linie1(), welche den Agenten dazu bringt, eine Linie aus 5 Blöcken mit dem Material deiner Wahl zu bauen. - Schreibe ein Programm, welches ein gefülltes Quadrat der Grösse 5 mal 5 Blöcke aus Gold baut (nutze eventuell die Lösung der Aufgabe 5). Versuche, einen möglichst kurzen Code zu produzieren!
- Füge in deinem Programm zur Aufgabe 6 eine Variable hinzu, sodass man das Baumaterial durch diese Variable festlegen kann.
mögliche Lösungen
Aufgabe 4
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen #Spirale kurzes Programm mit while def baueSpiralewhile(): drehRichtung = LEFT zaehler=0 # hier ist ein zähler nötig, da es eine while-Schleife ist. while ( zaehler<7): agent.move(FORWARD,zaehler) agent.turn(drehRichtung) zaehler=zaehler+1 baueSpiralewhile()
Aufgabe 5 - 7
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen #Linie, Funktion ohne Parameter für Linie aus 5 Blöcken def linie1(): agent.set_item(SANDSTONE,64,1) agent.set_slot(1) agent.move(FORWARD,5) linie1() # Funtion linie2 mit Parameter 'material', so kann das Baumaterial flexibel gewählt werden. def linie2(material): agent.set_item(material,64,1) agent.set_slot(1) agent.move(FORWARD,5) linie2(GOLD_BLOCK) #leeres Quadrat, nicht gefüllt. def quadrat(material): zaehler=0 while (zaehler < 5): linie2(material) agent.turn(LEFT_TURN) agent.move(FORWARD,1) zaehler=zaehler+1 agent.move(LEFT,1) quadrat(DIAMOND_BLOCK) #voll ausgefülltes Quadrat mit frei wählbarem Material. def quadrat2(material): zaehler=0 while (zaehler < 5): agent.set_assist(PLACE_ON_MOVE, True) linie2(material) agent.turn(LEFT_TURN) agent.move(FORWARD,1) agent.turn(LEFT) agent.set_assist(PLACE_ON_MOVE, False) linie2(material) agent.turn(LEFT) agent.turn(LEFT) agent.set_assist(PLACE_ON_MOVE, True) zaehler=zaehler+1 agent.set_assist(PLACE_ON_MOVE, False) agent.move(LEFT,1) quadrat2(GREEN_WOOL)
Oben wird die Variable drehRichtung innerhalb der Funktion baueSpirale definiert. Man kann sie dann nur innerhalb dieser Funktion verwenden: man spricht von einer lokalen Variablen. Würde man die Variable ausserhalb der Funktion (ganz zu Beginn des Codes) definieren, dann wäre sie überall im Programm sichtbar, auch für andere Funktionen lesbar. Globale Variablen sind wie Taucher, die unter Wasser für alle sichtbar sind. Lokale Variablen sind dagegen wie die Besatzung des U-Boots: Sie sind nur für die anderen Menschen im U-Boot sichtbar. Wenn man in Python eine globale Variable innerhalb einer Funktion verändern will, dann muss dies mit global deklariert sein, ansonsten erstellt Python eine gleichbenannte lokale Variable.
Funktion mit Parametern
Wenn man mit def eine eigene Funktion definiert, kann man diese flexibler machen, indem man Parameter verwendet. Dies sind Variablen, die beim Aufruf der Funktion übergeben werden und dann innerhalb der Funktion wie lokale Variablen funktionieren. So könnte man z.B. eine Funktion Hochhaus(n) definieren, welches ein Hochhaus mit n Etagen baut. Wenn man die Funktion dann aufruft, muss man für n einen konkreten Wert angeben: z.B. Hochhaus(7).
Das Beispiel unserer Spirale können wir mit Parametern etwas eleganter gestalten: wir übergeben der Funktion die Drehrichtung als Parameter.
- spiraleneu.py
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen def baueSpiraleNeu(richtung): agent.move(FORWARD,1) agent.turn(richtung) agent.move(FORWARD,2) agent.turn(richtung) agent.move(FORWARD,3) agent.turn(richtung) agent.move(FORWARD,4) agent.turn(richtung) agent.move(FORWARD,5) agent.turn(richtung) agent.move(FORWARD,6) baueSpiraleNeu(LEFT) agent.move(FORWARD, 10) baueSpiraleNeu(RIGHT) agent.move(FORWARD, 10) baueSpiraleNeu(LEFT) agent.move(FORWARD, 10) baueSpiraleNeu(RIGHT) agent.move(FORWARD, 10)
Nun können wir dieselbe Funktion verwenden, um rechtsdrehende und linksdrehende Spiralen zu bauen. Wir übergeben beim Aufruf der Funktion die Drehrichtung (Nun können wir dieselbe Funktion verwenden, um rechtsdrehende und linksdrehende Spiralen zu bauen. Wir übergeben beim Aufruf der Funktion die Drehrichtung (baueSpiraleNeu(Right)) und diese Drehrichtung ist dann innerhalb der Funktion an die Variable) und diese Drehrichtung ist dann innerhalb der Funktion an die Variable richtung gekoppelt (da wir bei der Definition der Funktion diesen Namen gewählt haben). gekoppelt (da wir bei der Definition der Funktion diesen Namen gewählt haben).
Aufgaben D
- Spiralen:
- Studiere das neue Programm für die Spirale. Wird der Agent dieses Mal dasselbe bauen wie vorher? Erkläre.
- Verändere das Programm so, dass der Agent zwei Spiralen aneinander baut, eine nach links drehend und eine nach rechts drehend.
- Linien:
- Schreibe eine Funktion
linie1(), welche den Agenten dazu bringt, eine Linie der Länge 5 zu bauen. Wähle den Baustein selber aus der Liste der Materialen aus. - Schreibe eine Funktion
linie2(n), welche den Agenten dazu bringt, eine Linie der Länge n zu bauen, indem er n Schritte vorwärts geht und die Linie als Blöcke hinter sich platzert. Wähle den Baustein selber aus der Liste Zusammenfassung der wichtigsten Blöcke/Materialien - Schreibe eine Funktion
linie3(n), welche den Agenten dazu bringt, eine Linie der Länge n zu bauen, indem er n Schritte vorwärts geht und die Linie aus unterschiedlichen Blöcken hinter sich platzert. (Die gesetzen Blöcke können die Baustein-ID n haben - Siehe dazu Zusammenfassung der wichtigsten Blöcke/Materialien). Teste mit verschiedenen Linien.
Notiere die wichtisten drei Erkenntnisse der Aufgaben in eigenen Worten und mit einem Beispiel. Dies ist für eine Prüfungsvorbereitung sehr nützlich!
mögliche Lösungen
Aufgabe 4
agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(SANDSTONE,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen #Spirale kurzes Programm mit while def baueSpiralewhile(): drehRichtung = LEFT zaehler=0 # hier ist ein zähler nötig, da es eine while-Schleife ist. while ( zaehler<7): agent.move(FORWARD,zaehler) agent.turn(drehRichtung) zaehler=zaehler+1 baueSpiralewhile()
Aufgaben 1b und 2
#Aufgabe 1b agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(BLUE_WOOL,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen def baueSpiraleNeu(richtung): i=0 while (i<6): agent.move(FORWARD,i) agent.turn(richtung) i=i+1 def baueSpiraleumgekehrt(richtung): i=0 while (i<7): agent.move(FORWARD,7-i) agent.turn(richtung) i=i+1 def baueZusammengesetzeSpirale(richtung): baueSpiraleNeu(LEFT) baueSpiraleumgekehrt(RIGHT) baueZusammengesetzeSpirale(LEFT)
Aufgabe 2a
# Linie bauen agent.set_assist(PLACE_ON_MOVE, True) # Agent baut, wenn er sich bewegt agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen agent.set_item(BLUE_WOOL,64,1) # 64 Blöcke Sandstein ins erste Fach des Inventars legen #Linie der Länge 5 def linie(): agent.set_assist(PLACE_ON_MOVE, True) agent.move(FORWARD,5) linie() #Linie der Länge n def linie2(n): agent.set_assist(PLACE_ON_MOVE, True) agent.move(FORWARD,n) linie2(7) #Linie mit unterschiedlichen Blöcken der Länge n. #Erinnerung % bedeutet Modulo def linie3(n): agent.set_assist(PLACE_ON_MOVE, True) while (n>0): if (n%3==0): agent.set_item(RED_WOOL, 64, 1) agent.set_slot(1) agent.move(FORWARD,1) elif (n%3==1): agent.set_item(BLUE_WOOL, 64, 2) agent.set_slot(2) agent.move(FORWARD,1) else: agent.set_item(YELLOW_WOOL, 64, 3) agent.set_slot(3) agent.move(FORWARD,1) n=n-1 linie3(7)
3. Listen (Arrays) erstellen, durchgehen und der range-Befehl
Listen erstellen
Mit eckigen Klammern kann man in Python eine Liste erstellen. Dabei können die einzelnen Elemente der Liste ganz unterschiedliche Typen haben. Es können sogar selbst wieder Listen sein. Auf die einzelnen Elemente der Liste kann man zugreifen, indem man den Namen der Liste mit eckigen Klammern und dem Index angibt (der Index bezeichnet die Position des Elementes in der Liste - er beginnt bei 0. Gibt man als Index negative Zahlen an, so zählt Python vom letzten Element an rückwärts. D.h. das letzte Element der Liste Liste1 erhält man mit erhält man mit Liste1[-1]).).
>>> Liste1 = [1, 2, 3, 4, 5] >>> Liste2 = [51, "Hallo", True, 3.141592] >>> Liste1[1] 2 >>> Liste1[2] Hallo >>> Liste2[-1] 3.141592 >>>
Listen verwendet man oft, wenn man viele Daten speichern muss. Statt dass man z.B. zehn Variablen Listen verwendet man oft, wenn man viele Daten speichern muss. Statt dass man z.B. zehn Variablen v1=5, v2=3, v3=8, v4=9,…, v10=0.34 definiert, erstellt man besser eine Liste definiert, erstellt man besser eine Liste v = [5,3,8,9,…,0.34] und greift dann auf die Werte zu, indem man und greift dann auf die Werte zu, indem man v[0], , v[1] etc. aufruft. Dadurch wird nur eine Variable vom Typ Liste genutzt und nicht viele Variabeln beispielsweise vom Typ float. etc. aufruft. Dadurch wird nur eine Variable vom Typ Liste genutzt und nicht viele Variabeln beispielsweise vom Typ float.
Aufgabe E
Gegeben ist eine Liste von Baumaterialien:
Materialien=[RED_SANDSTONE, GRASS, WOOL, DIAMOND_BLOCK, GOLD_BLOCK]
Schreibe ein Programm, welches den Agenten dazu bringt, eine Linie mit fünf verschieden Blöcken aus den Materialien der Liste zu bauen. Die Reihenfolge der Liste soll dabei eingehalten werden.
Tipps:
- Dein Code beginnt mit
Materialien=[RED_SANDSTONE, GRASS, WOOL, DIAMOND_BLOCK, GOLD_BLOCK] - Die Liste muss in deinem Code verwendet werden
- Verwende unter anderem die Befehle
agent.set_itemundagent.set_slot
mögliche Lösungen
Aufgabe E
def linie4(): materialien=[RED_SANDSTONE, GRASS, WOOL, DIAMOND_BLOCK, GOLD_BLOCK] agent.set_assist(PLACE_ON_MOVE, True) i=0 while (i<5): agent.set_item(materialien[i], 64, i+1) agent.set_slot(i+1) agent.move(FORWARD,1) i=i+1 linie4()
Der range-Befehl
Sehr häufig möchte man eine regelmässige Liste von Zahlen erstellen: z.B. alle Zahlen von 1 bis 10 oder die Zahlen von 1 bis 100 in 2er-Schritten etc.Sehr häufig möchte man eine regelmässige Liste von Zahlen erstellen: z.B. alle Zahlen von 1 bis 10 oder die Zahlen von 1 bis 100 in 2er-Schritten etc. Dazu ist der range-Befehl sehr praktisch. Dieser kann in drei Varianten genutzt werden:Dazu ist der range-Befehl sehr praktisch. Dieser kann in drei Varianten genutzt werden:
| range-Befehl | Bedeutung |
|---|---|
range(Endzahl) | Erstellt eine Liste der Zahlen von 0 bis und ohne die Endzahl in Einerschritten. |
range(10) | Liste der Zahlen von 0 bis 10 (exklusive 10), also [0,1,2,3,4,5,6,7,8,9] |
range(Startzahl, Endzahl) | Erstellt eine Liste von und mit der Startzahl bis und ohne der Endzahl in Einerschritten. |
range(4,9) | Liste der Zahlen von 4 (inkl.) bis 9 (exkl.), also [4,5,6,7,8] |
range(Startzahl, Endzahl, Schrittweite) | Erstellt eine Liste von und mit der Startzahl bis und ohne der Endzahl in der angegebenen Schrittweite. |
range(13,25,3) | Liste der Zahlen von 13 (inkl.) bis 25 (exkl.) in 3er-Schritten, also [13,16,19,22] |
Aufgabe F
Erstelle mit dem range-Befehl die folgenden Listen:
L1die Liste der ganzen Zahlen zwischen 0 und 8.L2die Liste der ganzen Zahlen, die kleiner als 20 und durch 3 teilbar sind.L3die Liste der ganzen Zahlen zwischen 20 und 40, die durch 4 teilbar sind.
Tipp: Mit dem Befehl player.say kannst du im Codebuilder deine Listen anzeigen lassen. Beispiel: player.say(L1)
mögliche Lösungen
Aufgabe F 1. bis F 3.
def liste1(): for i in range (8): player.say(i) liste1() #durch 3 teilbare Zahlen def liste2(): for i in range (20): if i%3==0: player.say(i) else: pass liste2() #durch 4 teilbare Zahlen def liste3(): for i in range (20, 40,4): player.say(i) liste3()
Listen abklappern (durchgehen)
Ganz oft will man für alle Elemente in einer Liste dasselbe tun, d.h. man will die Liste „abklappern“ (durchlaufen) und dann für jedes Element dieselbe Aktion durchfühen. Z.B. hat man eine Liste von Positionen und möchte bei jeder Position ein Haus bauen, oder man hat eine Liste von Baumaterialien und man möchte für jedes dieser Materialien einen Block platzieren etc.
Dafür gibt es in Python den Befehl for <Variable> in <Liste>. Am besten versteht man dies an einem Beispiel. Wir verbessern unser Programm, welches die Spirale baut, weiter:
def baueSpirale(richtung): agent.move(FORWARD,1) agent.turn(richtung) agent.move(FORWARD,2) agent.turn(richtung) agent.move(FORWARD,3) agent.turn(richtung) agent.move(FORWARD,4) agent.turn(richtung) agent.move(FORWARD,5) agent.turn(richtung) agent.move(FORWARD,6)
Wir sagen Python einfach: Gehe alle Zahlen von 1 bis 6 durch (sage der Variablen z.B. zahl) und mache dann die beiden Befehle:
agent.move(FORWARD,zahl) agent.turn(richtung)
Damit sieht unser Programm viel kürzer aus:
def baueSpirale(richtung): for zahl in [1,2,3,4,5,6]: agent.move(FORWARD,zahl) agent.turn(richtung)
Die Liste [1,2,3,4,5,6] können wir uns natürlich auch mit dem Range-Befehl erstellen lassen:
def baueSpirale(richtung): for zahl in range(1,7): agent.move(FORWARD,zahl) agent.turn(richtung)
for i in range(10) verwenden. for i in range(10): # i geht die Zahlen von 0 bis 9 durch agent.move(FORWARD,2) agent.place(BACK)
Allgemein werden for-Schleifen verwendet, wenn man weiss, wie oft ein Skriptteil wiederholt werden soll. Wenn die For-Schleife eine Liste abarbeiten soll, dann ist der range()-Befehl nötig.
for i in range(k): # i geht die Zahlen von 0 bis k durch Programm wird ausgeführt
Aufgabe G
Schreibe das Programm aus Aufgabe E kürzer. Gehe wie folgt vor:
- Fülle das Inventar des Agenten mit Hilfe des
for-Befehls und der Materialienliste - Baue die Linie mit den fünf Materialien des Inventars mit Hilfe eines
Range-Befehls.
mögliche Lösungen
def linie4plus():
materialien=[RED_SANDSTONE, GRASS, WOOL, DIAMOND_BLOCK, GOLD_BLOCK]
agent.set_assist(PLACE_ON_MOVE, True)
for i in range (4):
agent.set_item(materialien[i], 64, i+1)
agent.set_slot(i+1)
agent.move(FORWARD,1)
linie4plus()
Aufgaben H
- Schreibe eine Funktion
LinieZwei(n), welche eine Linie mit zwei selbst gewählten Materialien baut, wobei es jeweils abwechselt. - Schreibe eine Funktion
LinieDrei(n), welche eine Linie mit drei selbst gewählten Materialien baut, wobei es jeweils abwechselt mit allen drei Materialien. - Schreibe eine Funktion
LinieDoppelt(n), welche eine Linie mit Höhe zwei Blöcke und Länge n baut. Das Baumaterial ist frei wählbar. - Schreibe eine Funktion
LinieMitHöhe(n,h), welche eine Linie mit Höhe zwei Blöcke und Länge n und Höhe h baut. - Schreibe eine Funktion
Quadrat(n), welche den Agenten dazu bringt, ein nicht ausgefülltes Quadrat der Länge n zu bauen. - Schreibe eine Funktion
Quadratf(n)welche ein gefülltes Quadrat baut. - Schreibe eine Funktion
Tower(n,h)welche einen Turm mit quadratischer Grundfläche der Breite n und der Höhe h baut.
mögliche Lösungen
Aufgabe 1
def linieZwei(n): materialZwei=[GOLD_BLOCK,DIAMOND_BLOCK] for i in range (n): if i%2==0: agent.set_item(materialZwei[i%2],64,i%2+1) agent.set_slot(i%2+1) agent.set_assist(PLACE_ON_MOVE, True) agent.move(FORWARD,1) else: agent.set_item(materialZwei[i%2],64,i%2+1) agent.set_slot(i%2+1) agent.set_assist(PLACE_ON_MOVE, True) agent.move(FORWARD,1) linieZwei(8)
Aufgabe 2
def linieDrei(n): materialZwei=[GOLD_BLOCK,GLASS, GREEN_WOOL] for i in range (1,n,1): if i%3==0: agent.set_item(materialZwei[i%3],64,i%3+1) agent.set_slot(i%3+1) agent.set_assist(PLACE_ON_MOVE, True) agent.move(FORWARD,1) elif i%3==1: agent.set_item(materialZwei[i%3],64,i%3+1) agent.set_slot(i%3+1) agent.set_assist(PLACE_ON_MOVE, True) agent.move(FORWARD,1) else: agent.set_item(materialZwei[i%3],64,i%3+1) agent.set_slot(i%3+1) agent.set_assist(PLACE_ON_MOVE, True) agent.move(FORWARD,1) linieDrei(8)
Aufgabe 3
def linieDoppelt(n): agent.set_item(GOLD_BLOCK,64,1) agent.set_slot(1) agent.set_assist(PLACE_ON_MOVE, True) for i in range(1,n,1): agent.place(UP) agent.move(FORWARD,1) linieDoppelt(5)
Aufgabe 4
def linieMitHoehe(n,h):
agent.set_item(GOLD_BLOCK,64,1)
agent.set_slot(1)
for i in range (n):
agent.set_assist(PLACE_ON_MOVE, True)
agent.move(UP,h)
agent.set_assist(PLACE_ON_MOVE, False)
agent.move(FORWARD,1)
agent.move(DOWN,h)
linieMitHoehe(3,5)
Aufgabe 5
def quadrat(n): agent.set_item(BLUE_WOOL,64,1) agent.set_slot(1) agent.set_assist(PLACE_ON_MOVE, True) for i in range (4): agent.move(FORWARD,n) agent.turn_right() agent.move(LEFT,1) Quadrat(7)
Aufgabe 6
def Quadratf(n):
agent.set_item(BLUE_WOOL,64,1)
agent.set_slot(1)
agent.set_assist(PLACE_ON_MOVE, True)
for i in range (1,n,2):
agent.move(FORWARD,n-1)
agent.turn_right()
agent.move(FORWARD,1)
agent.turn_right()
agent.move(FORWARD,n-1)
agent.turn_left()
agent.move(FORWARD,1)
agent.turn(LEFT)
if n%2==1:
agent.move(FORWARD,n-1)
agent.turn_right()
agent.move(FORWARD,1)
agent.turn_right()
else:
pass
Quadratf(8)
Aufgabe 7
#Tower(n,h) welche einen Turm mit quadratischer #Grundfläche der Breite n und der Höhe h baut. def Tower(n,h): for i in range (h): Quadratf(n) agent.set_assist(PLACE_ON_MOVE, False) agent.move(UP,1) agent.move(LEFT,n) Tower(2,3)
4. Verzweigungen mit ''if'' und Schleifen mit ''while''
Verzweigungen mit if
Mit der Mit der if Anweisung kann man Befehle nur dann ausführen lassen, wenn eine bestimmte Bedingung Anweisung kann man Befehle nur dann ausführen lassen, wenn eine bestimmte Bedingung wahr (True) ist. Durch diese Anweisung kann eine Entscheidung programmiert werden. (True) ist. Durch diese Anweisung kann eine Entscheidung programmiert werden.
# Wenn ein Block vor dem und links vom Agenten liegt, # dreht sich der Agent nach links. Sonst, was bedeutet, # der Weg ist frei, macht der Agent einen Schritt vorwärts. if (agent.detect(AgentDetection.BLOCK, FORWARD)==True): agent.turn(LEFT) else: agent.move(FORWARD,1)
Schleifen mit "while"
Wir haben bereits die for-Schleife gesehen, um Befehle zu wiederholen. Mit der while-Schleife kann man das auch tun, wobei die Wiederholung nicht durch eine Liste gesteuert ist (wie bei der for-Schleife) sondern durch eine Bedingung. Solange die Bedingung wahr (True) ist, werden die Befehle wiederholt:
# Solange ein Block vor dem und links vom Agenten liegt, # und somit der Weg ist frei, macht der Agent einen Schritt vorwärts. while (agent.detect(AgentDetection.BLOCK, FORWARD)==False): agent.place(BACK) agent.move(FORWARD,1)
While-Schleifen werden verwendet, wenn man nicht weiss, wie oft der Schleifeninhalt wiederholt werden soll und man aus diesem Grund keine for-Schleife verwenden kann. Die Anzahl Wiederholungen kann beispielsweise von einer Eingabe abhängen. While-Schleifen sind können auch als Endlos-Schleife formuliert werden. Schleifenkörper können weitere Schleifen beinhalten, dies sind dann sogenannte Verschachtelte Schleifen. Eine For-Schleife kann eine While-Schleife beinhalten oder auch umgekehrt.
Aufgabe I
- Schreibe mit
whileein Programm, das den Agenten vorwärts gehen lässt, bis er auf einen Block stösst - Schreibe mit
whileein Programm, so dass der Agent vorwärts geht und alle Blöcke vor ihm zerstört, bis er auf einen Diamant-Block stösst. - Schreibe mit
whileein Programm, so dass der Agent vorwärts geht, solange ein Block rechts von ihm ist. - Lade das Labyrinth auf deinen Computer und versuche den Algorithmus „Gehe immer so, dass die Mauer rechts von dir ist“ zu programmieren. labyrinth.zip
mögliche Lösungen
Aufgabe 1
def Vorwaerts(): agent.set_assist(DESTROY_OBSTACLES,False) # Agent zerstört Hindernisse beim Bauen nicht agent.set_assist(PLACE_ON_MOVE, False) # Agent baut nicht, wenn er sich bewegt while True: agent.move(FORWARD,1) Vorwaerts()
Aufgabe 2
#Schreibe mit while ein Programm, so dass der Agent vorwärts #geht und alle Blöcke vor ihm zerstört, bis er auf einen Diamant-Block stösst. def VorwaertsBisDiamant(): agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen nicht agent.set_assist(PLACE_ON_MOVE,False) # Agent baut nicht, wenn er sich bewegt while (agent.inspect(AgentInspection.BLOCK, FORWARD) != 57): # Die Zeichenfolge != heisst nicht gleich. agent.move(FORWARD,1) VorwaertsBisDiamant()
Aufgaben 3
def VorwaertsBeiREchts(): agent.set_assist(DESTROY_OBSTACLES,True) # Agent zerstört Hindernisse beim Bauen nicht agent.set_assist(PLACE_ON_MOVE,False) # Agent baut nicht, wenn er sich bewegt while (agent.detect(AgentDetection.BLOCK, RIGHT) == True): # schaut, ob rechts etwas ist agent.move(FORWARD,1) VorwaertsBeiREchts()
