Lektion 2

Fallunterscheidungen
Durch Kontrollstrukturen (hier die if-Abfrage) kann kontrolliert werden, wann (und später auch wie lange) bestimmte Teile des Codes ausgeführt werden
Ab Kapitel 1.3.2 „repairTheStreet“ verändert sich die Welt um Karel herrum jedes mal, wen das Kapitel neu geladen wird (siehe Video).
Also brauchen wir eine neue Möglichkeit, um unseren Code an die stetig neuen Welten anzupassen.
Verdeutlichen wir uns das doch einfach mal am Beispiel von Kapitel 1.2.2 „fillTheHoles“ an.
Der Unterschied zu 1.3.2 „repairTheStreet“ ist, dass sich die Welt hier nicht verändert. Da zudem der Abstand (ein Loch alle 2 Felder) immer gleich ist, können wir hier ausnahmsweise „repeat“ verwenden.

Karel muss also erkennen, ob eine Wand (hier) rechts von ihm ihm ist!
Karel kennt fünf elementare Bedingungen
F7 | onBeeper() | Karel prüft, ob auf dem Platz, auf dem er gerade steht, ein Beeper liegt |
F8 | beeperAhead() | Karel prüft, ob sich ein Beeper auf dem Platz unmittelbar vor ihm befindet |
F9 | leftIsClear() | Karel prüft, ob sich keine Mauer zwischen ihm und dem Platz links von ihm befindet |
F10 | frontIsClear() | Karel prüft, ob sich keine Mauer zwischen ihm und dem Platz vor ihm befindet |
F11 | rightIsClear() | Karel prüft, ob sich keine Mauer zwischen ihm und dem Platz rechts von ihm befindet |
So geht’s:
Achte auf die { } – Klammern

Welche Bedingung wird hier benötigt?
Und so wird es im Programm umgesetzt
Bedingung erfüllt
Bedingung nicht immer erfüllt
Hinweis: onBeeper() überprüft, ob Karel auf einem Beeper steht.
Hinweis: Mit einem Linksklick auf ein Kreuz, könnt ihr Beeper setzen oder entfernen!

Für alle Fälle?
Der Anfang und das Ende können schwierig sein und stimmen nicht immer direkt von Anfang an (auch wenn der Rest perfekt funktioniert).
-> Ladet jedes Kapitel mehrfach (wie ganz oben im Video gezeigt) und überprüft, ob euer Code auch wirklich immer Funktioniert!
Im Beispiel von Kapitel 1.3.2 solltet ihr also kontrollieren, was passiert, wenn ganz am Anfang oder ganz am Ende ein Loch in der Straße ist.
1.3.2 "repairTheStreet"
Der Code muss ähnlich zu dem Code oben (aus der Erklärung) aufgebaut werden.
Achte darauf, wann der Befehl moveForwand() ausgeführt werden soll. Das ist oben extra etwas anders programmiert.
void repairTheStreet(){
repeat(9){
if(rightIsClear()){ // Reihenfolge wichtig, falls direkt am Anfang ein Loch ist
turnRight();
moveForward();
dropBeeper();
turnAround();
moveForward();
turnRight();
}
moveForward();
}
// Reihenfolge wichtig, falls ganz am Ende ein Loch ist … Muss nochmal aufgerufen werden
if(rightIsClear()){
turnRight();
moveForward();
dropBeeper();
turnAround();
moveForward();
turnRight();
}
}
Funktioniert euer Code auch, wenn ein Loch am Anfang und am Ende ist?
Ladet das Level ein paar mal Neu und probiert es aus
1.3.3 "cleanTheRoom"
Karel hat 3 verschiedene Bewegungsmuster
Laufen
Drehen (am rechten Rand)
Drehen (am linkem Rand)
Warum nicht 3 Funktionen daraus machen!
void cleanTheRoom(){
repeat(5){
Gerade();
Linksdrehung();
Gerade();
Rechtsdrehung();
}
}
void Gerade(){
repeat(9){
if(onBeeper()){
pickBeeper();
}
moveForward();
}
if(onBeeper()){
pickBeeper();
}
}
void Linksdrehung(){
turnLeft();
moveForward();
turnLeft();
}
void Rechtsdrehung(){
if(rightIsClear()){
turnRight();
moveForward();
turnRight();
}
}

Das Semikolon beendet einen Befehl
Zur besseren lesbarbekit (aus Platzgründen) können Befehle hintereinander geschrieben.
Dem Programm ist egal, ob in eurem Code jeder Befehl in einer neuen Zeile steht (alles untereinander) oder eben nicht. Indem ihr ein Semikolon ; setzt, weiß dass Programm, dass der Befehl an der stelle beendet ist
moveForward();
moveForward();
moveForward(); moveForward();
Üblicherweise wird jedoch jeder Befehl in eine neue Zeile geschrieben (da der Code dann leichter zu lesen ist).

Die if-else-Anweisung
Normalerweise wird das Zusammenspiel von if-else verwendet: Wenn – Sonst
Wird if nicht ausgeführt, wird else automatisch aufgerufen
Wird if ausgeführt, wird else übersprungen
So können auch komplexere Abfragen erstellt (implementiert) werden
Diese Regeln müssen beachtet werden:
In else kommt KEINE Bedingung
Wird if nicht ausgeführt, wird else automatisch aufgerufen
Wird if ausgeführt, wird else übersprungen
Stehen vorher mehrere if-Abfragen, wird else nur ausgeführt, wenn KEINE if ausgeführt wurde
Sonst (wenn eine oder mehrere if-Anweisungen) ausgeführt werden, wird else übersprungen
else muss NACH if stehen
Vervollständige das Bild - Wo endet Karels Weg? (5 Aufgaben)
Aufgabe
Ziehe das X (aus dem Satz) auf das richtige Feld.
Zusätzlich kannst du die Beeper auf das Feld ziehen und wieder entfernt.
Code 1
Code 2
Code 3
Code 4
Code 5
Hinweis: Die (eigentliche) Lösung „goal“ von Kapitel 1.3.4 überspringen wir an dieser Stelle. 1.3.4 „fillTheHoles“ betrachten wir in der nächsten Lektion: Hier werden die sogenannten Vergleichsoperatoren verwendet.
Kapitel 1.4.1 "stealOlympicFire"
Die Treppe ist die selbe wie in Kapitel 1.2.1, aber wir können ja jetzt if/else-Abfragen.
Verwende if/else!
Erstelle dir eine Funktion Treppe() zum hochlaufen.
Das Einsammeln und herunterlaufen ist nicht sonderlich kompliziert.
void stealOlympicFire(){
Treppe(); // würde auch mit Kapitel 1.2.1 gehen -> schöner mit if/else
pickBeeper();
moveForward();
turnRight();
repeat(6){
moveForward();
}
turnLeft();
moveForward();
}
// Wir unterscheiden, ob Karel momentan vor einer Stufe steht oder nicht
void Treppe(){
repeat(13){
if(frontIsClear()){
moveForward();
}
else{
turnLeft();
moveForward();
turnRight();
}
}
}
Kapitel 1.4.2 "removeTheTiles"
Nutze die repeat-Anweisung
repeat(100){ … }
Dann muss du nur unterscheiden, ob sich gerade ein Beeper in der Nähe befindet
void removeTheTiles(){
repeat(100){
pickBeeper();
if(beeperAhead()){
moveForward();
}
else{
turnLeft();
moveForward();
}
}
}