Aufgaben: Hamster-Finale
Unser Ziel ist es, dass der Hamster ein beliebiges Labyrinth durchlaufen kann und zum Ziel (= ein Korn) findet. Die einzige Einschränkung: Das Labyrinth muss „zyklenfrei“ sein, was bedeutet, dass der Hamster nicht im Kreis (Zyklus) laufen kann. Die Gänge des Labyrinths sind zudem genau eine Kachel breit. Nachfolgend befindet sich ein Beispiel-Labyrinth.
Ist das obige Labyrinth wirklich zyklenfrei? Prüfe mit dem Auge. Erkläre, welche Mauer du umsetzen könntest, um einen Zyklus in das Labyrinth einzufügen.
Der Hamster soll eine ganz einfache Strategie verwenden, sich nämlich „immer links halten“. Ganz konkret:
- Falls das Feld links frei ist, soll er einen Schritt nach links gehen.
- Falls nicht, jedoch das Feld geradaus frei ist, soll er einen Schritt geradeaus gehen.
- Falls nicht, jedoch das Feld rechts frei ist, soll er einen Schritt nach rechts gehen.
- Falls auch dies nicht der Fall ist, handelt es sich um eine Sackgasse. In diesem Fall soll er sich umdrehen.
Was wir hier benötigen, sind die Funktionen linksFrei und rechtsFrei. Die bekannte Funktion vornFrei ist bereits vordefiniert. Hier die Funktion linksFrei:
boolean linksFrei()
{
linksUm();
// Jetzt pruefen, ob vorne frei ist. Die vordefinierte Funktion `vornFrei` liefert
// entweder `true` oder `false` zurueck. Dieses Ergebnis wird in der neuen Variablen
// `frei` gespeichert.
boolean frei = vornFrei();
// Nun wieder nach rechts zurück drehen - schliesslich wollen wir nur herausfinden,
// ob links frei ist, und nicht den Hamster nach links gedreht stehen lassen.
rechtsUm();
// Erst nach dem Zurueckdrehen geben wir den gespeicherten Wahrheitswert zurueck.
return frei;
}
Nach der oben beschriebenen Strategie ist es hilfreich, mit einer Funktion rechtsFrei abfragen zu können, ob der Hamster nach rechts gehen kann. Schreibe die Funktion rechtsFrei analog zu linksFrei.
boolean rechtsFrei()
{
rechtsUm();
boolean frei = vornFrei();
linkssUm();
return frei;
}
Schreibe ein Programm, das den Hamster ein beliebiges zyklenfreies Labyrinth durchlaufen lässt. Der Hamster hat die Aufgabe bewältigt, wenn er auf das Korn gestoßen ist.
Verwende folgendes Grundgerüst.
void main()
{
while (!kornDa())
{
// TODO: Hier die oben vorgeschlagene Strategie implementieren
}
}
boolean linksFrei()
{
// TODO: Bitte einfuegen
}
boolean rechtsFrei()
{
// TODO: Bitte einfuegen
}
void main()
{
while (!kornDa())
{
if (linksFrei())
{
linksUm();
vor();
}
else if (vornFrei())
{
vor();
}
else if (rechtsFrei())
{
rechtsUm();
vor()
}
else
{
linksUm();
linksUm();
}
}
}
boolean linksFrei()
{
linksUm();
boolean frei = vornFrei();
rechtsUm();
return frei;
}
boolean rechtsFrei()
{
rechtsUm();
boolean frei = vornFrei();
linksUm();
return frei;
}
void rechtsUm()
{
linksUm();
linksUm();
linksUm();
}
Herzlichen Glückwunsch, du beherrscht die Grundlagen des imperativen Programmierens in Java! Mit „imperativ“ ist übrigens „befehlsorientiert“ gemeint − schließlich springt der Rechner von Befehl zu Befehl. Es gibt aber auch noch andere Programmierstile (Teaser). Bevor wir nun aber in die objektorientierte Programmierung einsteigen (eine Erweiterung der imperativen Programmierung um... naja, Objekte!), entwirf eine eigene Hamsteraufgabe (gerne mit Partner/in!).
Formuliere eine eigene Aufgabenstellung für den Hamster. Er kann Berge erkimmen, Kornfelder abräumen, mit dem Benutzer/in „sprechen“, rechnen, Hürden laufen, Tänze aufführen, Buchstaben legen, Labyrinthe durchlaufen, Fährten verfolgen, ...
Entwirf ein dazugehöriges Programm. Greife dabei auf die bis jetzt kennengelernten Werkzeuge zurück:
- Prozeduren, um wiederkehrende Routinen zu definieren
- Variablen, um Zahlen und Wahrheitswerte zu speichern
- Prozeduren mit Parametern, um für jeden Aufruf neue Werte an die Prozedur zu übergeben
- Funktionen, um eine Aktion auszuführen, die einen Rückgabewert liefert