Lektion 1

Karel the Robot

Der Aufbau von Funktionen

Die einzelnen Bestandteile

Funktionsname

In der Lernumgebung muss für jedes Kapitel eine neue Funktion erstellt werden.

Generell gilt:

Keine Umlaute/Sonderzeichen/Leerzeichen: (also kein ä, ü, ö, ß , …) .

Der Name sollte auch nicht nur aus einem Großbuchstaben bestehen.

Klammern ( )

Hinter dem Namen stehen runde Klammern.

Klammern { }

Die Befehle (Anweisungen) kommen zwischen die geschweiften Klammern.

Um die Zusammengehörigkeit des abzuarbeitenden Codes zu markieren, werden die auszuführenden Anweisungen (Befehle) üblicherweise in einem Bereich mit geschweiften Klammern { } eingefasst. Die zusammengefassten Anweisungen werden als Anweisungsblock bezeichnet.

 

Für die Lernumgebung bedeutet das, dass für jedes Kapitel eine neuer Anweisungsblock (eine neue Funktion) erstellt werden muss.

 

Genau so erstellen wir später auch Zählschleifen, if/else-Abfragen und Schleifen.

Für die geschweiften Klammern { }

Windows

[ AltGr – 7 ] und [ AltGr – 0]

macOS

[ Alt – 8 ] und [ Alt – 9 ]

 

 

Generell gilt: Suche das Symbol auf deiner Tastatur und verwende die richtige Tastenkombination (je nachdem, ob das Symbol hochgestellt oder daneben ist):

Hiweis: Das Beispiel gilt für Windows

 

 

 

 

Datentyp void

void ist ein sogenannter Dtentyp.

 

In der Lernumgebung wird nur dieser Datentyp verwendet, daher müssen wir an dieser Stelle nicht weiter darauf eingehen.

Natürlich gibt es mehrere Datentypen (beispielsweise int). Die Unterschiede werden in der Arduino-Reihe genauer betrachtet. Durch unterschiedliche Dtentypen können Funktionen beispielsweise Werte zurückgeben oder reservieren unterschiedlich viel Speicherplatz auf einem Chip.

Zählschleifen

Um Befehle mehrfach zu verwenden, kann „repeat (#Anzahl)“ verwendet werden. Statt den Befehl moveForward() 4x zu schreiben, können wir ihn auch einfach 4x wiederholen.

Lernumgebung - Sprachreferenz_Funktionen_erstellen

void karelsRun(){

moveForward();
moveForward();
moveForward();
moveForward();


turnAround();

 

moveForward();
moveForward();
moveForward();
moveForward();

}

void karelsRun(){

 

repeat(4) {

moveForward();

}

 

turnAround();

 

 

repeat(4) {

moveForward();

}

}

Hinweis: Natürlich können in der Repeat-Anweisung auch mehrere Befehle stehen.

1.1.1 "obtainArtifact" mit Zählschleifen

Nutze diesmal die repeat-Anweisung

repeat(Anzahl){

}

 

Die repeat-Anweisung kann in den „normalen Code“ geschrieben werden.

 

Befehl();
Befehl();

repeat(Anzahl){

}

Befehl();

 

Genau wie oben (Funktionen erstellen) müssen alle Befehle (hier also moveForword(); ) in die geschweifte Klammer.

 

In die runde Klammer wird die Anzahl an Wiederholungen geschrieben (hier 3).

void obtainArtifact() {

turnRight();
moveForward();
turnLeft();

 

repeat(3){                         // 3x wiederholen

moveForward();

}

 

turnLeft();
moveForward();
pickBeeper();
moveForward();
turnLeft();

 

repeat(3){                         // 3x wiederholen

moveForward();

}

 

turnLeft();
moveForward();
turnLeft();

}

Erstellen und aufrufen von Funktionen

Wir können(neben den erstellen von Funktionen für einzelne Kapitel) auch beliebig viele andere Funktionen erstellen. Dabei müüsen die Regln von oben zur benennung unbedingt beachtet werden.

Funktionen erstellen

void Name(){

Anweisung;
Anweisung;

}

Funktionen aufrufen

Name();

Wir können jede Funktion aufrufen.

Anders als beim erstellen einer Funktion verwenden wir dazu nur den Namen (mit den runden Klammern) und enden mit einem Simikolon ;

Tastenkombination:

 

Das Semikolon beendet eine Anweisung.

moveForward();

 

Die Befehle können auch hintereinander geschrieben werden.

Das wir die Befehle bisher immer untereinander geschrieben haben lag einfach daran, dass es für den Menschen leichter zu lesen ist – dem Programm ist es egal -> das Semikolon beendet eine Anweisung.

moveForward(); moveForward()moveForward();

Beispiel
Wir erstellen die Funktion run()

void run() {

moveForward();
moveForward();
moveForward();
moveForward();

}

Wir rufen die Funktion run() auf

void Hin_Und_Her(){

run();

turnAround();

run();

}

Die Funktion run() wird hier in der Funktion Hin_Und_Her aufgerufen. Damit passiert wieder das selbe, wie oben.

 

Wir hätten auch wieder karelsRun verwenden können, da

run(); und Run();  und karelsRun() unterschiedliche Funktionen sind -> Groß- und Kleinschreibung beachten!!

1.1.2 " defuseOneBomb"

Erstelle eine „neue“ Funktion und rufe sie auf.

Nennen kannst du die Funktion, wie du willst.

 

void defuseOneBomb(){

run();

}

     

In dem Video (mit der Lösung) siehst du, wie (wann) das Programm die Funktionen aufruft.

void defuseOneBomb(){

run();
pickBeeper();
run();

}

 

 

void run (){

repeat(9){

moveForward();

}

turnAround();

}

1.1.3" defuseTwoBombs"

Mehr als 3 Anweisungen (Befehle) solltest du hier nicht brauchen!

Rufe „alte“ Funktionen auf, die du schon programmiert hast.

void defuseTwoBombs(){

defuseOneBomb();
turnLeft();
defuseOneBomb();

}

1.1.4 "practiceHomeRun"

Ihr habt beim programmieren oft mehrere Möglichkeiten.

Wie wäre es erneut mit Funktionsaufrufen oder (wie unten in „Code“) einfach mal mit einer repeat-Anweisung in einer repeat-Anweisung. Achte dabei auf die { } Klammern.

void practiceHomeRun(){

repeat(4){

repeat(9){

moveForward();

}

pickBeeper();
turnLeft();

}

}

1.2.1 "climbTheStairs"

Bisher stand in jeder repeat-Anweisung nur ein Befehl.

Natürlich könnt ihr auch mehrere Befehle hineinschreiben, die nacheinander ausgeführt werden.

void climbTheStairs(){

repeat(6){

moveForward();
turnLeft();
moveForward();
turnRight();

}
moveForward();

}

1.2.2 "fillTheHoles"

void fillTheHoles(){

repeat(4){

moveForward();
turnRight();
moveForward();
dropBeeper();
turnAround();
moveForward();
turnRight();
moveForward();

}

}

Kommentare

Kommentare sind Codeteile, die vom Programm nicht ausgeführt werden.

Kommentare sind für den Menschen, nicht für das Programm! Indirekt hast du sie bereits kennengelernt. In vielen der Videos oben findest du Kommentare als zusätzliche Erklärung (in grün). In den Codeschnippseln (Lösungen zum ausklappen) wurde bisher darauf verzichtet.

1 Zeile auskommentieren

// Alles, was hinter den 2 Strichen steht, wird nicht ausgeführt (Kommentar)

mehrere Zeile auskommentieren

/*

 * So können auch mehrere Zeilen auskommentiert werden

 *

 * (das sind alles auskommentierte Zeilen)

*/

1.2.3 "saveTheFlower"

Nur ein gut kommentierter Code ist ein guter Code!

Über in den nächsten Kapitel mit Kommentaren umzugehen und ergänze deinen eigenen Code so mit nützlichen Hinweisen/Erklärungen.

Teilt euch den Code auf

Pyramide hochlaufen

oben

Pyramide runterlaufen

„unten“

void saveTheFlower(){

moveForward();
pickBeeper();

 

repeat(4){                   // Pyramide hoch

turnLeft();
moveForward();
moveForward();
turnRight();
moveForward();

}

 

dropBeeper();              // oben
moveForward();

 

repeat(3){                   // runterlaufen

turnRight();
moveForward();
moveForward();
turnLeft();
moveForward();

 }

 

 turnRight();          // das darf nicht in die letzte repeat, weil er sonst gegen die Wand läuft
 moveForward();
 moveForward();
 turnLeft();

}

1.2.4 "mowTheLawn"

Achte darauf, wo und wie Karel am Ende stehen soll <goal> und ob dein Code das auch so macht <start>.

Oft läuft Karel hier etwas weiter, als er eigentlich ´soll. Dann hast du zu viel in der repeat-Anweisung stehen und musst irgendetwas anders machen!

void mowTheLawn(){

repeat(2){

Reihe_1_Und_2();
letztesDrehen();

}

Reihe_1_Und_2();
moveForward();

}

 

 

// Mit selbst definierten Funktionen wird es leichter

void Reihe_1_Und_2(){

repeat(6){

moveForward();
pickBeeper();

}

repeat(2){

moveForward();
turnLeft();

}

repeat(6){

moveForward();
pickBeeper();

}

}

 

void letztesDrehen(){

repeat(2){

moveForward();
turnRight();

}

}

1.3.1 "harvestTheField"

Schau dir das Bewegungsmuster von Karel mal genau an. Um die 4 Beeper auf der Diagonalen einzusammeln (beispielsweise die ersten 4), hat er immer die gleichen Bewegungen.

Starte damit, in dem du dir eine Funktion [bsp „void Diagonal()“ ] erstellst.

void harvestTheField(){

Diagonal();
Ende();
Diagonal();
turnAround();
Diagonal();
Ende();
Diagonal();

}

 

 

void Diagonal(){

repeat(4){

moveForward();
pickBeeper();
turnRight();
moveForward();
turnLeft();

}

}

 

void Ende(){

repeat(2){

moveForward();
moveForward();
turnLeft();

}

}