// Ein Labyrinth-Spiel // Autor: Fritz Bökler // Datum 20.11.2024 // MIT Lizenz // // Labyrinth wird in der Konsole ausgegeben. // . Leeres Feld // # Wand (nicht betretbar) // Z Ziel // S SpielerIn (wird nicht im Labyrinth gespeichert) // // Ziel des Spiels ist, das Ziel-Feld zu erreichen. // Eingabe erfolgt zeilengepuffert über cin. #include "std_lib_inc.h" // Globale Labyrinth-Definition als konstanter Ausdruck constexpr int kRows = 5; constexpr int kCols = 5; // Labyrinth-Daten // Interpretiere als Zeilen, dann Spalten const vector> kMaze = { {'#', '.', '.', '.', '.'}, {'#', '.', '#', '.', '.'}, {'.', 'Z', '#', '.', '.'}, {'.', '#', '#', '#', '.'}, {'.', '.', '.', '.', '.'}, }; const vector kPlayerStartPosition = {4, 0}; // Funktion zur Anzeige des Labyrinths // player_position: Position der SpielerIn im Labyrinth void display_maze(vector player_position) { int player_row = player_position[0]; int player_col = player_position[1]; for(int i = 0; i < kRows; i++) { for(int j = 0; j < kCols; j++) { if(i == player_row && j == player_col) { cout << 'S'; } else { cout << kMaze[i][j]; } cout << " "; } cout << '\n'; } } // Funktion zur Umrechnung eines Kommandos zu einer neuen Position // player_position: Position der SpielerIn im Labyrinth // direction: Richtungskommando // Rückgabe: Die neue SpielerInnenposition // Vorbedingung: direction muss aus {w, s, a, d} kommen. vector new_position_by_direction(vector player_position, char direction) { int row = player_position[0]; int col = player_position[1]; assert(direction == 'w' || direction == 's' || direction == 'a' || direction == 'd', "new_position_by_direction: invalid direction. Must be from {w, s, a, d}."); switch(direction) { case 'w': return {row - 1, col}; case 's': return {row + 1, col}; case 'a': return {row, col - 1}; case 'd': return {row, col + 1}; } } // Gibt true zurueck gdw. die Position position begehbar ist // position: Zu testende Position // Rückgabe: true gdw. die Position begehbar ist bool position_is_valid(vector position) { const int row = position[0]; const int col = position[1]; bool outside_playfield = row < 0 || col < 0 || row >= kRows || col >= kCols; if(outside_playfield) // Erst prüfen, bevor Vector-Zugriff { return false; } return kMaze[row][col] != '#'; } // Funktion zur Bewegung des Spielers // player_position: Position der SpielerIn vor der Bewegung // direction: Richtungskommando // Rückgabe: Die neue SpielerInnenposition der SpielerIn vector move_player(vector player_position, char direction) { vector potential_new_position = new_position_by_direction(player_position, direction); if(position_is_valid(potential_new_position)) { return potential_new_position; } else { cout << "Bewegung nicht moeglich!\n"; return player_position; } } // Gibt eine kurze Hilfe aus void display_help() { cout << "Willkommen zum Labyrinth-Spiel!\n"; cout << "Ziel des Spiels: Finde den Weg vom Startpunkt (S) zum Ziel (Z).\n"; cout << "Spielfeld-Erklaerung:\n"; cout << "S - Startpunkt: Hier beginnt der Spieler.\n"; cout << "Z - Ziel: Erreiche diesen Punkt, um das Spiel zu gewinnen.\n"; cout << "# - Wand: Diese Felder sind nicht begehbar.\n"; cout << ". - Leeres Feld: Diese Felder koennen betreten werden.\n"; cout << "\nSteuerung:\n"; cout << "w - Nach oben bewegen\n"; cout << "a - Nach links bewegen\n"; cout << "s - Nach unten bewegen\n"; cout << "d - Nach rechts bewegen\n"; cout << "Nach jeder Befehlseingabe muss die Eingabetaste (Enter) gedrueckt werden, um sich zu bewegen.\n"; cout << "\nViel Erfolg im Labyrinth!\n"; } // Reagiert auf das eingegebene Kommando und gibt an die jeweilige Funktion // ab, die sich um genau dieses Kommando kuemmert. // player_position: die aktuelle SpielerInnenposition // input: Ein Eingabezeichen // Rückgabe: Die neue SpielerInnenposition, falls sie sich aendert vector process_input(vector player_position, char input) { switch(input) { case 'w': case 's': case 'a': case 'd': return move_player(player_position, input); case 'h': display_help(); break; default: cout << "Diese Eingabe kenne ich nicht. Gib 'h' ein, um eine Hilfe zu erhalten.\n"; break; } return player_position; } // Gibt true zurueck, wenn das Ziel erreicht wurde // player_position: Die aktuelle SpielerInnenposition // Rückgabe: true gdw. das Ziel erreicht wurde bool reached_goal(vector player_position) { return kMaze[player_position[0]][player_position[1]] == 'Z'; } // Die Hauptschleife des Spiels // player_position: Die aktuelle SpielerInnenposition void game_loop(vector player_position) { char input; bool not_won = true; while(cin && not_won) { display_maze(player_position); cin >> input; if(cin) { player_position = process_input(player_position, input); if(reached_goal(player_position)) { display_maze(player_position); cout << "Ziel erreicht! Herzlichen Glueckwunsch!\n"; not_won = false; } } } } int main() { game_loop(kPlayerStartPosition); return 0; }