Jahrgangsstufe Ef - Informatik - Dienstag, der 16. März 2021


Rekursion

Mein Name:
Jahrgang/Klasse:
Meine E-Mail-Adresse:

Musterlösungen

Zur Orientierung und Wiederholung der Rekursion gibt es für die Aufgaben vom 02., 04. und 09.03. Musterlösungen.

Information 1 (wie am 11.03.):

Ganz nützlich für viele Situationen können die folgenden beiden Methoden sein:

  public void turnAround()
  { kara.turnLeft();
    kara.turnLeft();
  }

  public void moveBack()
  { turnAround();
    kara.move();
    turnAround();
  }

Information 2 (wie am 11.03.):

Kara hat für Blätter nur den Sensor kara.onLeaf(), kann also nur feststellen, ob ein Blatt direkt unter ihm liegt. Wir wissen aber, wie man Funktionen programmiert, die ebenso einen booleschen Wert true oder false zurückliefern. Hier ein Beispiel:

  public boolean leafFront()
  { boolean blatt=false; // false, wenn vorne Baum steht
    if (!kara.treeFront())
         { // jetzt muss man nachschauen
           kara.move();
           blatt=kara.onLeaf(); // blatt uebernimmt den booleschen
           moveBack();         // Funktionswert von onLeaf()
         }
    return blatt;
  }

Nun kann man in einem Programm (nach der Ergänzung von leafLeft()) auch Abfragen wie

  if(leafFront() || leafLeft())

machen. Das erfordert zwar etwas mehr sportliche Bewegung für den Marienkäfer, aber das tut in Corona-Zeiten jedem ganz gut.

Auftrag:

Kara bewacht ein Mobilé (Wer nicht weiß, was das ist, recherchiert selbständig). Die Drähte und Fäden sind hier als Kleeblätter dargestellt. Er macht regelmäßig einen Kontrollgang über alle Drähte, um lästige Insekten, die sich an den Enden niedergelassen haben, vom Drahtgestell zu stoßen. Die Insekten sind hier als Pilze dargestellt(kara.mushroomFront()=true). Er soll rekursiv alle Wege entlanglaufen jeweils bis zum Ende (Pilz oder nicht), sich umdrehen und jeweils den gleichen Weg (den er sich rekursiv "gemerkt hat) zurückgehen. Die dargestellte Kara-Welt kann hier heruntergeladen werden (Abspeichern als Mobile2021.world und im rechten Javakara-Weltfenster öffnen).
Das Programm ist hier schon strukturiert weitgehend vorgegeben. Es darf aber auch je nach Bedarf und Idee anders strukturiert werden. Z. B. könnte man den ersten und den letzten Fall zusammenfassend behandeln.

import javakara.JavaKaraProgram;
public class Mobile extends JavaKaraProgram
{
  void turnAround()
  { kara.turnLeft();
    kara.turnLeft();
  }

  void moveBack()
  { turnAround();
    kara.move();
    turnAround();
  }

  boolean leafFront()
  { boolean blatt=false;   // auch false, wenn vorne Baum steht
    if (!kara.treeFront()) // jetzt muss man nachschauen
         { kara.move();
           blatt=kara.onLeaf();
           moveBack();
         }
    return blatt;
  }

  boolean leafLeft()
  { boolean blatt=false;  // auch false, wenn links Baum steht
    if (!kara.treeLeft()) // jetzt muss man nachschauen
         { kara.turnLeft();
           kara.move();
           blatt=kara.onLeaf();
           moveBack();
           kara.turnRight();
         }
    return blatt;
  }

  boolean leafRight()
  { boolean blatt=false;   // auch false, wenn links Baum steht
    if (!kara.treeRight()) // jetzt muss man nachschauen
         { kara.turnRight();
           kara.move();
           blatt=kara.onLeaf();
           moveBack();
           kara.turnLeft();
         }
    return blatt;
  }

  void zumUngeziefer()
  { if (kara.mushroomFront()) // Ende mit Ungeziefer erreicht.
         { kara.move();       // Pilz wird einfach weggeschoben und
           turnAround();      // damit der Schaedling abgeworfen.
           kara.move();       // Rekursionabbruch!
         }
    else if (leafFront())     // Es geht ganz einfach vorne weiter.
         { kara.move();       // Einen Schritt vor.
           zumUngeziefer();   // Problem von dort loesen.
           kara.move();       // Auf Rueckweg einen Schritt vor.
         }
    else if (leafLeft() && leafRight()) // Verzweigung nach links und rechts
         {
           ...
         }
    else if (leafLeft())      // Der Weg knickt nach links ab.
         {
           ...
         }
    else if (leafRight())     // Der Weg knickt nach rechts ab.
         {
           ...
         }
    else {                    // vorne kein Blatt und keine Abzweigung mehr:
                              //Ende ohne Ungeziefer erreicht.
           turnAround();      // Abbruch der Rekursion.
         }
  }  // Ende von zumUngeziefer

  public void myProgram()
  { zumUngeziefer(); }
}  // Ende der Klasse Mobile

Vervollständige den Programmtext, teste das Programm und gib das komplette Programm hier ein.