Fallunterscheidungen

In einer Fallunterscheidung wird eine Bedingung getestet, z.B. vornFrei(), und je nach Ergebnis unterschiedlich fortgefahren.

if (vornFrei())
{
    // Konsequenz
}
else
{
    // Alternative
}
Falls...
  1. die Bedingung zu true auswertet: Die Konsequenz (if-Block) wird ausgeführt.
  2. die Bedingung zu false auswertet: Die Alternative (else-Block) wird ausgeführt. Falls nichts ausgeführt werden soll, darf man den ganzen Block weglassen.

Mehr Erklärungen zu Fallunterscheidungen findest du hier.

Die Körner sind in einer Reihe wahllos verstreut, auf jeder Kachel befindet sich maximal eines. Als Beispiel dient das rechtsstehende Territorium. Der Hamster soll sich auf den Weg machen und auf jeder Kachel das Korn nur dann aufsammeln, wenn es sich auch tatsächlich auf der Kachel befindet. Dafür soll eine Fallunterscheidung eingesetzt werden.

Das folgende Programm ist ein erster Ansatz: Der Hamster geht drei Schritte nach rechts und überprüft auf jeder Kachel, ob er auf einem Korn gelandet ist. Falls dem so ist, nimmt er das Korn auf.

void main()
{
    vor();
    if (kornDa())
    {
        nimm();
    }
    vor();
    if (kornDa())
    {
        nimm();
    }
    vor();
    if (kornDa())
    {
        nimm();
    }
}

Das kann man aber noch eleganter lösen! Wir definieren die Prozedur sicheresNimm, welche den Hamster nur dann ein Korn nehmen lässt, falls dies möglich ist. Somit ergibt sich folgendes kleines Programm:

void main()
{
    vor();
    sicheresNimm();
    vor();
    sicheresNimm();
    vor();
    sicheresNimm();
}

void sicheresNimm()
{
    if (kornDa())
    {
        nimm();
    }
}

Tippe das Programm ab. Dann erweitere das Programm so, dass alle 13 vor dem Hamster liegenden Felder abgegrast werden.

Der Hamster will sehnlichst einen Schritt nach vorne tun. Falls dies nicht möglich ist, so will er wenigstens einen Schritt nach links tun. Schreibe ein passendes Programm.

Beispiel-Szenario 1

Freie Bahn − der Hamster kann nach vorne gehen.

Vorher
Nachher

Beispiel-Szenario 2

Bahn blockiert − der Hamster muss nach links ausweichen.

Vorher
Nachher

Verwende eine Fallunterscheidung mit if-Block und else-Block. Lies dir auch nochmal die Erklärung zur Fallunterscheidung durch.

void main()
{
    if (vornFrei())
    {
        vor();
    }
    else
    {
        linksUm();
        vor();
    }
}

Der Hamster will immer noch sehnlichst einen Schritt nach vorne tun. Diesmal strengt er sich mehr an. Falls er nicht nach vorne gehen kann, so versucht er einen Ausweichschritt nach links zu machen und anschließend nach vorne zu gehen. Schreibe ein passendes Programm.

Beispiel-Szenario 1

Freie Bahn − der Hamster kann nach vorne gehen.

Vorher
Nachher

Beispiel-Szenario 2

Ausweichschritt gelingt.

Vorher
Nachher

Beispiel-Szenario 3

Ausweichschritt gelingt nicht.

Vorher
Nachher

Verwende eine Fallunterscheidung mit if-Block und else-Block. Lies dir auch nochmal die Erklärung zur Fallunterscheidung durch.

void main()
{
    if (vornFrei())
    {
        vor();
    }
    else
    {
        linksUm();
        vor();
    }
}

Der Hamster will seinen Briefkasten leeren. Dazu läuft er zunächst zum Briefkasten auf der Kachel ganz rechts. Es gibt zwei Möglichkeiten:

  1. Es liegt ein Brief (ein Korn) im Briefkasten. In diesem Fall führt er einen Freudentanz auf (einmal im Kreis drehen).
  2. Es liegt kein Brief (kein Korn) im Briefkasten. In diesem Fall trottet er wieder zurück.
Brief liegt drin. Kein Brief

Schreibe ein passendes Programm.

Fortgeschritten: Es gibt eine dritte Möglichkeit: Es liet ein Paket (zwei Körner) im Briefkasten. In diesem Fall führt er einen besonders großen Freudentanz auf (viermal im Kreis drehen).

Lasse den Hamster zunächst zum Briefkasten laufen. Anschließend prüfe, ob ein Brief da ist, indem du eine Fallunterscheidung mit der Bedingung kornDa() verwendest.

void main()
{
    // Laufe zum Briefkasten
    vor();
    vor();
    vor();
    vor();
    vor();
    
    // Nachschauen
    if (kornDa())
    {
        // Leeren
        nimm();
        // Freudentanz
        freudentanz();
    }
    else
    {
        // Zuruecklaufen
        linksUm();
        linksUm();
        vor();
        vor();
        vor();
        vor();
        vor();
    }
}

void freudentanz()
{
    linksUm();
    linksUm();
    linksUm();
    linksUm();
}

Der Hamster will sehnlichst irgendeinen Schritt tun. Falls möglich, geht er einen Schritt nach links. Falls nicht, probiert er, einen Schritt nach vorne zu gehen. Falls dies auch nicht möglich ist, geht er einen Schritt nach rechts.

Schreibe ein passendes Programm.

Tipp: Verwende eine verschachtelte Fallunterscheidung.

Zunächst dreht sich der Hamster nach links und probiert, einen Schritt voraus zu machen (if (vornFrei)). Nur wenn er scheitert (else), dreht er sich nach rechts (damit schaut er also wieder nach „vorne“) und probiert erneut (daher die Verschachtelung), einen Schritt voraus zu machen (if (vornFrei)).

Auch hierbei kann er scheitern (else). In diesem Fall dreht er sich nach rechts und geht einen Schritt voraus.

void main()
{
    // Probiere "links"
    linksUm();
    if (vornFrei())
    {
        vor();
    }    
    else
    {
        // Nach vorne schauen
        rechtsUm();
        // Probiere "vorne"
        if (vornFrei())
        {
            vor();
        }
        else
        {
            // Nach rechts schauen
            rechtsUm();
            // Probiere "rechts"
            if (vornFrei())
            {
                vor();
            }
        }
    }
}

void rechtsUm()
{
    linksUm();
    linksUm();
    linksUm();
}

Ein als Hamster verkleideter Maulwurf will seine Nahrung aufnehmen. Dazu muss er aber erstmal an die Erdoberfläche gelangen. Da er nicht mehr weiß, wie genau der Maulwurfsgang aussieht, muss er sich auf verschiedene Szenarien gefasst machen. Folgende Angaben sind bekannt.

  1. Der horizontale Gang ist bis zu vier Kacheln lang.
  2. Der vertikale Gang ist exakt drei Kacheln lang.
  3. Die Nahrung befindet sich auf der Erdoberfläche, eine Kachel links vom Maulwurfsgang.

Im Folgenden sind ein paar Beispiel-Territorien gezeigt.

Entwirf ein Programm, welches den Hamster seine Nahrung fressen lässt.

Definiere eine Prozedur sicheresVor, welche den Hamster nur dann einen Schritt nach vorne gehen lässt, falls die vor ihm liegende Kachel frei ist. Diese Prozedur kannst du im unteren Gang einfach vier Mal verwenden.

Anschließend muss der Hamster nur noch den Gang hochkrabbeln und das Korn einsammeln.

void main()
{
    sicheresVor();
    sicheresVor();
    sicheresVor();
    sicheresVor();
    linksUm();
    sicheresVor();
    sicheresVor();
    sicheresVor();
    sicheresVor();
    linksUm();
    vor();
    nimm();
}

void sicheresVor()
{
    if (vornFrei())
    {
        vor();
    }
}

Der Hamster will aus seiner Kachelwelt ausbrechen, kennt jedoch den Weg nicht. Er weiß nur, dass er genau 14 Schritte gehen muss. Zum Glück kann er Fährten lesen. Wenn er direkt auf eine Wand schaut, so liest er die Fährte auf seiner aktuellen Kachel.

  • Falls sich auf der Kachel ein Korn befindet, so geht er einen Schritt nach links.
  • Andernfalls geht er einen Schritt nach rechts.

Der Hamster kennt die genaue Route nicht. Es könnte z.B. eine von den folgenden drei Routen sein:

Betrachte die drei Beispiel-Territorien. Durchlaufe jeweils mit dem Auge den Weg des Hamsters und gleiche die Fährten mit der blau eingezeichneten Linie ab.

Schreibe ein Programm, welches den Hamster in jedem Fall zum Ziel gelangen lässt. Am Ziel darf er als Belohnung drei Körner fressen.

Definiere eine passende Prozedur schritt, welche du in der main-Prozedur 14 Mal aufrufst.

Die Prozedur schritt muss nun Folgendes prüfen: Falls der Hamster nach vorne gehen kann, so tut er dies. Andernfalls (else) prüft der Hamster, ob sich ein Korn auf der Kachel befindet. Falls ja, so geht er einen Schritt nach links. Falls nein, so geht er einen Schritt nach rechts.

void main()
{
    // 14 Schritte
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    schritt();
    // Im Ziel -- jetzt eine Belohnung!
    nimm();
    nimm();
    nimm();
}

void schritt()
{
    // Falls es nach vorne geht, gehe nach vorne!
    if (vornFrei())
    {
        vor();
    }
    // Andernfalls...
    else
    {
        // Signal lesen:
        // 1) Entweder ein Korn ist da, oder...
        if (kornDa())
        {
            linksUm();
            vor();
        }
        // 2) Kein Korn ist da:
        else
        {
            rechtsUm();
            vor();
        }
    }
}

void rechtsUm()
{
    linksUm();
    linksUm();
    linksUm();
}