Kapitel 5 · C++ verstehen
Jede Funktion ist ein Teammitglied
In eurem Programm hat jede Funktion eine eigene Aufgabe. Hier lernst du alle 12 kennen. Auf Wunsch kannst du den passenden C++-Code aufklappen.
01🧭Funktion 01 · switch · returnrobotSymbol()
Ein Richtungspfeil für den Roboter
🎯 Wozu brauchen wir sie?
Damit wir auf der Karte sofort sehen, wohin der Roboter schaut.
⚙️ Was macht sie?
Die Funktion bekommt eine Richtung, zum Beispiel EAST. Mit switch wählt sie das passende Zeichen: ^, >, v oder <.
💡 Beispiel: Schaut unser Roboter nach Osten, zeigt die Funktion „>“ an.
Den C++-Code ansehen ⌄
char robotSymbol(Direction dir) {
switch(dir) {
case NORTH: return '^';
case EAST: return '>';
case SOUTH: return 'v';
case WEST: return '<';
}
return '?';
}
Gut zu wissen: Die echte Datei enthält nach manchen return-Anweisungen noch break. Sie werden nicht ausgeführt, weil return die Funktion sofort beendet.
02🗺️Funktion 02 · for · cout · ifprintWorld()
Die Karte auf dem Bildschirm malen
🎯 Wozu brauchen wir sie?
So können wir beobachten, wo der Roboter steht und welche Felder er schon besucht hat.
⚙️ Was macht sie?
Die Funktion zeichnet die Welt Zeile für Zeile. Wo der Roboter gerade steht, zeichnet sie seinen Richtungspfeil. Danach gibt sie eine zweite Karte mit den Besuchszahlen aus.
💡 Beispiel: Steht der Roboter auf (0, 7) und schaut nach Osten, erscheint dort „>“. Beim Start hat dieses Feld die Besuchszahl 1.
Den C++-Code ansehen ⌄
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
if (x == robot.x && y == robot.y) {
cout << robotSymbol(robot.direction) << ' ';
} else {
cout << world[y][x] << ' ';
}
}
cout << endl;
}
Gut zu wissen: Dies ist der Ausschnitt, der die Spielfeld-Karte zeichnet. In der Originalfunktion wird außerdem die Besuchszahlen-Karte ausgegeben.
03👀Funktion 03 · Koordinaten · Referenzen (&)getFrontPosition()
Welches Feld liegt direkt vor mir?
🎯 Wozu brauchen wir sie?
Bevor ein Roboter losfährt, muss er wissen, welches Feld als Nächstes kommen würde.
⚙️ Was macht sie?
Die Funktion nimmt die aktuelle Position und verändert genau eine Koordinate: Norden heißt y−1, Süden y+1, Osten x+1, Westen x−1.
💡 Beispiel: Roboter bei (5, 4), Blick nach Osten: Das Feld vor ihm ist (6, 4).
Den C++-Code ansehen ⌄
frontX = robot.x;
frontY = robot.y;
switch(robot.direction) {
case NORTH: frontY--; break;
case SOUTH: frontY++; break;
case EAST: frontX++; break;
case WEST: frontX--; break;
}
Gut zu wissen: Durch int& frontX und int& frontY kann die Funktion beide Ergebnis-Koordinaten an die aufrufende Stelle zurückgeben.
04🚧Funktion 04 · bool · true/false · ||outsideWorld()
Bin ich noch innerhalb der Karte?
🎯 Wozu brauchen wir sie?
Der Roboter darf nicht über den Rand der Welt hinausfahren.
⚙️ Was macht sie?
Er überprüft: Ist x kleiner als 0 oder mindestens WIDTH? Ist y kleiner als 0 oder mindestens HEIGHT? Wenn ja, ist das Feld außerhalb.
💡 Beispiel: Bei einer 12 × 8-Karte sind x = 0 bis 11 und y = 0 bis 7 erlaubt. (12, 3) liegt außerhalb.
Den C++-Code ansehen ⌄
bool outsideWorld(int x, int y) {
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
return true;
}
return false;
}
05🧱Funktion 05 · Sensor · if · boolobstacleAhead()
Der unsichtbare Hindernissensor
🎯 Wozu brauchen wir sie?
Diese Funktion schützt den Roboter vor Wänden und Kartenrändern.
⚙️ Was macht sie?
Zuerst ermittelt sie das Feld vor dem Roboter. Dann prüft sie den Kartenrand. Nur wenn das Feld innerhalb der Karte liegt, schaut sie nach, ob dort ein # steht.
💡 Beispiel: Vor dem Roboter ist ein #? Dann antwortet der Sensor true: „Stopp, dort ist eine Wand!“
Den C++-Code ansehen ⌄
bool obstacleAhead(const Robot& robot) {
int frontX;
int frontY;
getFrontPosition(robot, frontX, frontY);
if (outsideWorld(frontX, frontY)) return true;
if (world[frontY][frontX] == '#') return true;
return false;
}
Gut zu wissen: Die Reihenfolge ist entscheidend: ZUERST Rand prüfen, DANN auf world[y][x] zugreifen.
06🚀Funktion 06 · Zustand ändern · !moveForward()
Genau einen Schritt fahren
🎯 Wozu brauchen wir sie?
Jetzt wird wirklich die Position des Roboters verändert – aber nur, wenn der Weg frei ist.
⚙️ Was macht sie?
Die Funktion berechnet die nächste Position. Meldet obstacleAhead() kein Hindernis, werden die Werte robot.x und robot.y aktualisiert.
💡 Beispiel: Von (5, 4) nach Osten: Nach dem Schritt steht der Roboter auf (6, 4) – sofern dort keine Wand ist.
Den C++-Code ansehen ⌄
void moveForward(Robot& robot) {
int nextX;
int nextY;
getFrontPosition(robot, nextX, nextY);
if (!obstacleAhead(robot)) {
robot.x = nextX;
robot.y = nextY;
}
}
Gut zu wissen: Wichtig: Diese Funktion erhöht den Besuchszähler nicht. Das erledigt think() direkt nach dem Schritt.
07↪️Funktion 07 · switch · DirectionturnRight()
Einmal nach rechts drehen
🎯 Wozu brauchen wir sie?
Beim Prüfen der Nachbarn muss der Roboter seine Blickrichtung ändern können.
⚙️ Was macht sie?
Die Funktion wechselt die Richtung im Kreis: NORTH → EAST → SOUTH → WEST → NORTH. Die Position bleibt unverändert.
💡 Beispiel: Er schaut nach Norden (^). Ein Rechtsdrehen macht daraus Osten (>).
Den C++-Code ansehen ⌄
void turnRight(Robot& robot) {
switch (robot.direction) {
case NORTH: robot.direction = EAST; break;
case EAST: robot.direction = SOUTH; break;
case SOUTH: robot.direction = WEST; break;
case WEST: robot.direction = NORTH; break;
}
}
08↩️Funktion 08 · Modulo % · enumturnLeft()
Einmal nach links drehen
🎯 Wozu brauchen wir sie?
Manchmal möchten wir den Roboter auch in die andere Richtung drehen.
⚙️ Was macht sie?
Diese Funktion verändert nur die Blickrichtung. Sie verwendet eine kurze Rechenregel mit +3 und %4.
💡 Beispiel: Norden (0) + 3 = 3: Das bedeutet Westen. „% 4“ sorgt dafür, dass die Werte im Bereich 0 bis 3 bleiben.
Den C++-Code ansehen ⌄
void turnLeft(Robot& robot) {
robot.direction =
static_cast<Direction>((robot.direction + 3) % 4);
}
Gut zu wissen: In der aktuellen Suchstrategie wird turnLeft() nicht aufgerufen. Der Roboter kann trotzdem nach links fahren, weil think() alle vier Richtungen mit turnRight() prüft.
09🏁Funktion 09 · Bedingung · RückgabewertgoalReached()
Haben wir das Ziel erreicht?
🎯 Wozu brauchen wir sie?
Die Suche muss stoppen, sobald der Roboter auf dem Feld G angekommen ist.
⚙️ Was macht sie?
Die Funktion schaut unter den Roboter: Wenn auf seiner jetzigen Position ein G steht, gibt sie true zurück, sonst false.
💡 Beispiel: Steht der Roboter bei (10, 1), also auf dem G der Originalkarte, ist die Mission geschafft.
Den C++-Code ansehen ⌄
bool goalReached(const Robot& robot) {
if (world[robot.y][robot.x] == 'G') {
return true;
}
return false;
}
10🔢Funktion 10 · Array · Prioritäten · numeric_limitsgetVisited()
Wie gut ist das Feld vor mir?
🎯 Wozu brauchen wir sie?
Das Roboter-Gehirn braucht für jeden Nachbarn eine Zahl, um verschiedene Wege vergleichen zu können.
⚙️ Was macht sie?
Die Funktion untersucht immer nur das Feld VOR dem Roboter. Für eine normale Zelle gibt sie ihren Besuchszähler zurück. Eine Wand oder ein Feld außerhalb bekommt eine riesige Zahl. Das Ziel G bekommt −1 und gewinnt dadurch immer.
💡 Beispiel: Vorne ist ein freies Feld mit zwei Besuchen → 2. Vorne ist G → −1. Vorne ist # → sehr große Zahl.
Den C++-Code ansehen ⌄
int getVisited(const Robot& robot) {
int frontX;
int frontY;
getFrontPosition(robot, frontX, frontY);
if (outsideWorld(frontX, frontY))
return numeric_limits<int>::max();
if (world[frontY][frontX] == '#')
return numeric_limits<int>::max();
if (world[frontY][frontX] == 'G')
return -1;
return visited[frontY][frontX];
}
Gut zu wissen: Die Besuchszahlen werden in visited[][] gespeichert, NICHT in world[][]. Die Weltkarte behält ihre Zeichen . # und G.
11🧠Funktion 11 · for · Vergleich < · Minimumthink()
Das Gehirn: Den nächsten Schritt auswählen
🎯 Wozu brauchen wir sie?
Diese Funktion entscheidet, wohin der Roboter fährt. Sie enthält unsere eigentliche Suchstrategie.
⚙️ Was macht sie?
Der Roboter schaut nach vorne, nach rechts, nach hinten und nach links. Er merkt sich die Richtung mit dem niedrigsten Wert aus getVisited(). Danach stellt er sich in diese Richtung, fährt einen Schritt und erhöht genau dort den Besuchszähler.
💡 Beispiel: Vorne 3, rechts 0, hinten 2, links Wand: Das Gehirn wählt rechts. Stehen vorne und rechts beide auf 0, gewinnt vorne.
Den C++-Code ansehen ⌄
bool think(Robot& robot) {
Direction bestDirection = robot.direction;
int lowestVisits = numeric_limits<int>::max();
for (int i = 0; i < 4; ++i) {
int count = getVisited(robot);
if (count < lowestVisits) {
lowestVisits = count;
bestDirection = robot.direction;
}
turnRight(robot);
}
if (lowestVisits == numeric_limits<int>::max())
return false;
robot.direction = bestDirection;
moveForward(robot);
visited[robot.y][robot.x]++;
return true;
}
Gut zu wissen: Vier Rechtsdrehungen bringen den Roboter wieder in die ursprüngliche Richtung. Das Zeichen < in if (count < lowestVisits) ist wichtig: Bei Gleichstand bleibt die zuerst geprüfte Richtung Sieger.
12🎬Funktion 12 · Startwerte · Schleife · returnmain()
Hier beginnt das Abenteuer
🎯 Wozu brauchen wir sie?
main() ist der Startknopf für das ganze Programm.
⚙️ Was macht sie?
main() stellt den Roboter auf seine Startposition, zählt das Startfeld als besucht und startet dann die Schleife: Karte zeigen → Ziel prüfen → denken und fahren → kurz warten.
💡 Beispiel: Start: x = 0, y = 7, Richtung EAST. Nach spätestens 500 Schleifendurchläufen beendet die Sicherheitsgrenze die Suche.
Den C++-Code ansehen ⌄
robot.x = 0;
robot.y = 7;
robot.direction = EAST;
visited[robot.y][robot.x] = 1;
const int MAX_STEPS = 500;
for (int step = 1; step <= MAX_STEPS; step++) {
printWorld(robot);
if (goalReached(robot)) return 0;
if (!think(robot)) return 1;
this_thread::sleep_for(chrono::milliseconds(200));
}
Gut zu wissen: Wichtig: MAX_STEPS = 500 ist eine Sicherheitsgrenze, kein Beweis, dass kein Weg existiert. Das Ziel wird in dieser Programmversion am Anfang jedes Schleifendurchlaufs geprüft.