197 lines
5.6 KiB
C++
197 lines
5.6 KiB
C++
|
// 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<vector<char>> kMaze = {
|
||
|
{'#', '.', '.', '.', '.'},
|
||
|
{'#', '.', '#', '.', '.'},
|
||
|
{'.', 'Z', '#', '.', '.'},
|
||
|
{'.', '#', '#', '#', '.'},
|
||
|
{'.', '.', '.', '.', '.'},
|
||
|
};
|
||
|
|
||
|
const vector<int> kPlayerStartPosition = {4, 0};
|
||
|
|
||
|
// Funktion zur Anzeige des Labyrinths
|
||
|
// player_position: Position der SpielerIn im Labyrinth
|
||
|
void display_maze(vector<int> 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<int> new_position_by_direction(vector<int> 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<int> 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<int> move_player(vector<int> player_position, char direction)
|
||
|
{
|
||
|
vector<int> 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<int> process_input(vector<int> 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<int> player_position)
|
||
|
{
|
||
|
return kMaze[player_position[0]][player_position[1]] == 'Z';
|
||
|
}
|
||
|
|
||
|
// Die Hauptschleife des Spiels
|
||
|
// player_position: Die aktuelle SpielerInnenposition
|
||
|
void game_loop(vector<int> 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;
|
||
|
}
|