feat: added exception types and game object for handing game state
This commit is contained in:
parent
884e72d7b5
commit
eda62c7c6d
10 changed files with 266 additions and 96 deletions
|
@ -7,13 +7,18 @@ include_directories(.)
|
|||
|
||||
add_executable(epr24pr3_ojanssen2
|
||||
main.cpp
|
||||
std_lib_inc.h
|
||||
Player.cpp
|
||||
Player.h
|
||||
PositionVector.cpp
|
||||
PositionVector.h
|
||||
std_lib_inc.h
|
||||
Maze.h
|
||||
Maze.cpp
|
||||
MazeParser.h
|
||||
MazeParser.cpp
|
||||
Game.h
|
||||
Game.cpp
|
||||
Exceptions/MovementNotPossible.h
|
||||
Exceptions/MalformedMaze.h
|
||||
Exceptions/UnkownAction.h
|
||||
)
|
||||
|
|
26
Exceptions/MalformedMaze.h
Normal file
26
Exceptions/MalformedMaze.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Created by moonleay on 12/17/24.
|
||||
//
|
||||
|
||||
#ifndef MALFORMEDMAZE_H
|
||||
#define MALFORMEDMAZE_H
|
||||
|
||||
namespace game_exceptions
|
||||
{
|
||||
class MalformedMaze
|
||||
{
|
||||
string why;
|
||||
|
||||
public:
|
||||
MalformedMaze(string why): why(why)
|
||||
{
|
||||
}
|
||||
|
||||
string what()
|
||||
{
|
||||
return this->why;
|
||||
}
|
||||
};
|
||||
} // game_exceptions
|
||||
|
||||
#endif //MALFORMEDMAZE_H
|
26
Exceptions/MovementNotPossible.h
Normal file
26
Exceptions/MovementNotPossible.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Created by moonleay on 12/17/24.
|
||||
//
|
||||
|
||||
#ifndef MOVEMENTNOTPOSSIBLE_H
|
||||
#define MOVEMENTNOTPOSSIBLE_H
|
||||
|
||||
namespace game_exceptions
|
||||
{
|
||||
class MovementNotPossible
|
||||
{
|
||||
string why;
|
||||
|
||||
public:
|
||||
MovementNotPossible(string why): why(why)
|
||||
{
|
||||
}
|
||||
|
||||
string what()
|
||||
{
|
||||
return this->why;
|
||||
}
|
||||
};
|
||||
} // game_exceptions
|
||||
|
||||
#endif //MOVEMENTNOTPOSSIBLE_H
|
26
Exceptions/UnkownAction.h
Normal file
26
Exceptions/UnkownAction.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Created by moonleay on 12/17/24.
|
||||
//
|
||||
|
||||
#ifndef UNKOWNACTION_H
|
||||
#define UNKOWNACTION_H
|
||||
|
||||
namespace game_exceptions
|
||||
{
|
||||
class UnkownAction
|
||||
{
|
||||
string why;
|
||||
|
||||
public:
|
||||
UnkownAction(string why): why(why)
|
||||
{
|
||||
}
|
||||
|
||||
string what()
|
||||
{
|
||||
return this->why;
|
||||
}
|
||||
};
|
||||
} // game_exceptions
|
||||
|
||||
#endif //UNKOWNACTION_H
|
122
Game.cpp
Normal file
122
Game.cpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
//
|
||||
// Created by moonleay on 12/17/24.
|
||||
//
|
||||
|
||||
#include "Game.h"
|
||||
#include "MazeParser.h"
|
||||
#include "Player.h"
|
||||
#include "Maze.h"
|
||||
#include "Exceptions/MovementNotPossible.h"
|
||||
#include "Exceptions/UnkownAction.h"
|
||||
|
||||
using game::Player;
|
||||
using game::Maze;
|
||||
using game_exceptions::UnkownAction;
|
||||
using game_exceptions::MovementNotPossible;
|
||||
|
||||
namespace game // Namespace = Scope with name and no features
|
||||
{
|
||||
Game::Game(): maze({}, {}), player(0, 0)
|
||||
{
|
||||
// Lese das Labyrinth ein
|
||||
maze = MazeParser::request_maze_from_user();
|
||||
|
||||
// Lese die Startpositon des Spielers aus dem eingelesenen Labyrinth aus
|
||||
vector<int> player_start_position = maze.get_player_start_position();
|
||||
|
||||
// Überschreibe den Spieler mit der gegebenen Startposition
|
||||
this->player = Player(player_start_position[1], player_start_position[0]);
|
||||
}
|
||||
|
||||
PositionVector Game::handle_user_input(char input)
|
||||
{
|
||||
// Erstelle einen Vector mit einer Bewegung von 0 und 0
|
||||
PositionVector movement_vector = PositionVector(0, 0);
|
||||
|
||||
// Kontrolliere, was der Spieler machen möchte. Speichere die erforderte Bewegung im Bewegungsvektor.
|
||||
// Schreibe nachrichten in die Konsole,
|
||||
// wenn nach Hilfe gefragt wird oder eine unbekannte Eingabe eingegeben wurde
|
||||
switch (input)
|
||||
{
|
||||
case 'w':
|
||||
movement_vector.update(0, -1);
|
||||
break;
|
||||
case 'a':
|
||||
movement_vector.update(-1, 0);
|
||||
break;
|
||||
case 's':
|
||||
movement_vector.update(0, 1);
|
||||
break;
|
||||
case 'd':
|
||||
movement_vector.update(1, 0);
|
||||
break;
|
||||
case 'h':
|
||||
// Schreibe hilfsreiche Tipps in die Konsole
|
||||
cout <<
|
||||
"Du wurdest von einem Zauberer in ein Labyrinth gesperrt, nachdem du seine Künste beleidigt hast.\n"
|
||||
<< "Er laesst dich leben, wenn du es schaffst den Ausgang (Z) zu finden. Solltest du keinen Erfolg haben, laesst er dich verhungern.\n"
|
||||
<< "Auf deinem Abenteuer wirst du dabei boesen Geistern (A) begegnen und mit Schluesseln (K) Tueren (T) aufschliessen.\n"
|
||||
<< "Bewege dich mit 'w', 'a', 's' und 'd'.\n";
|
||||
break;
|
||||
default:
|
||||
// Die gewollte Aktion kenne ich nicht. Melde Fehler dem Nutzer
|
||||
throw UnkownAction("Diese Eingabe kenne ich nicht. Gib 'h' ein, um eine Hilfe zu erhalten.");
|
||||
}
|
||||
|
||||
return movement_vector;
|
||||
}
|
||||
|
||||
void Game::run_game()
|
||||
{
|
||||
// Erstelle eine Variable für den Input
|
||||
char game_input;
|
||||
|
||||
// Durchlaufe die Hauptschleife des Spiels
|
||||
while (true)
|
||||
{
|
||||
// Zeige dem Spieler das Spielfeld
|
||||
maze.render(player);
|
||||
|
||||
// Kontrolliere, ob der Spieler an einem Geist gestorben ist
|
||||
if (maze.was_player_killed_by_ghost(player))
|
||||
{
|
||||
cout << "Sie haben einen Geist getroffen! Game Over!\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// Kontrolliere, ob der Spieler schon das Ziel erreicht hat
|
||||
if (maze.is_player_at_goal(player))
|
||||
{
|
||||
// Ziel erreicht! Herzlichen Glückwunsch!
|
||||
cout << "Ziel erreicht! Herzlichen Glueckwunsch!\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// Lese Eingabe des Spielers
|
||||
cin >> game_input;
|
||||
|
||||
PositionVector movement_vector = PositionVector(0, 0);
|
||||
|
||||
try
|
||||
{
|
||||
movement_vector = handle_user_input(game_input);
|
||||
} catch (UnkownAction& err)
|
||||
{
|
||||
cout << err.what() << "\n";
|
||||
}
|
||||
|
||||
|
||||
// Kontrolliere gewollte Bewegung und setze sie um.
|
||||
try
|
||||
{
|
||||
maze = player.move(maze, movement_vector);
|
||||
}
|
||||
catch (MovementNotPossible& err)
|
||||
{
|
||||
// Diese Bewegung ist nicht möglich!
|
||||
// Gebe aus, warum.
|
||||
cout << err.what() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
} // game
|
33
Game.h
Normal file
33
Game.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// Created by moonleay on 12/17/24.
|
||||
//
|
||||
#include "Maze.h"
|
||||
#include "Player.h"
|
||||
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
namespace game
|
||||
{
|
||||
/// Eine Instanz des Spiels
|
||||
class Game
|
||||
{
|
||||
private:
|
||||
Maze maze;
|
||||
Player player;
|
||||
|
||||
public:
|
||||
Game();
|
||||
|
||||
/// Bearbeite die Eingabe des Spielers
|
||||
/// @param input Die Eingabe des Nutzers
|
||||
/// @return Der Bewegungsvektor, um den sich den Spieler bewegen möchte
|
||||
/// @throws UnkownAction Wenn die Eingabe des Spielers unbekannt ist
|
||||
static PositionVector handle_user_input(char input);
|
||||
|
||||
/// Starte das Spiel
|
||||
void run_game();
|
||||
};
|
||||
} // game
|
||||
|
||||
#endif //GAME_H
|
4
Maze.h
4
Maze.h
|
@ -25,10 +25,6 @@ namespace game
|
|||
/// Das Spielfeld
|
||||
Maze(vector<vector<char>> play_field, vector<int> player_start_position);
|
||||
|
||||
/// Ein Standard Konstruktor
|
||||
/// Variablen innerhalb der Klasse bleiben leer
|
||||
Maze() = default;
|
||||
|
||||
/// Kontrolliere, ob der Spieler stirbt
|
||||
/// @param player Der Spieler
|
||||
/// @return Ob der Spieler tot ist
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
#include "MazeParser.h"
|
||||
|
||||
#include "Exceptions/MalformedMaze.h"
|
||||
|
||||
using game_exceptions::MalformedMaze;
|
||||
|
||||
namespace game
|
||||
{
|
||||
vector<int> MazeParser::request_numbers_from_user(const int amount_of_numbers)
|
||||
|
@ -22,7 +26,7 @@ namespace game
|
|||
|
||||
// Sollte etwas schiefgelaufen sein, dann wirf eine Exception
|
||||
if (!cin)
|
||||
throw runtime_error("Cin failed while reading numbers!");
|
||||
throw MalformedMaze("Cin failed while reading numbers!");
|
||||
|
||||
// Schreibe die gelesene Zahl auf die Liste
|
||||
list.push_back(input);
|
||||
|
@ -68,11 +72,11 @@ namespace game
|
|||
|
||||
// Werfe eine Exception, wenn der Input nicht lesbar ist, d.h. Nutzer hat eine Falsch eingabe getätigt.
|
||||
if (!cin)
|
||||
throw runtime_error("Cin failed while reading chars!");
|
||||
throw MalformedMaze("Cin failed while reading chars!");
|
||||
|
||||
// Kontrolliere, ob das Element in einem Labyrinth vorkommen darf
|
||||
if (!is_valid_maze_element(input))
|
||||
throw runtime_error("The given input is not a valid element of a maze!");
|
||||
throw MalformedMaze("The given input is not a valid element of a maze!");
|
||||
|
||||
// Schreibe den eingelesenen Wert in die aktuelle Reihe
|
||||
row.push_back(input);
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "std_lib_inc.h"
|
||||
#include "Player.h"
|
||||
#include "Maze.h"
|
||||
#include "Exceptions/MovementNotPossible.h"
|
||||
|
||||
using game_exceptions::MovementNotPossible;
|
||||
|
||||
namespace game
|
||||
{
|
||||
|
@ -55,7 +58,7 @@ namespace game
|
|||
}
|
||||
}
|
||||
else
|
||||
throw runtime_error("Bewegung nicht moeglich!");
|
||||
throw MovementNotPossible("Bewegung nicht moeglich!");
|
||||
return maze;
|
||||
}
|
||||
|
||||
|
|
103
main.cpp
103
main.cpp
|
@ -1,113 +1,42 @@
|
|||
#include "Maze.h"
|
||||
#include "std_lib_inc.h"
|
||||
#include "Player.h"
|
||||
#include "Maze.h"
|
||||
#include "PositionVector.h"
|
||||
#include "MazeParser.h"
|
||||
#include "Game.h"
|
||||
#include "Exceptions/MalformedMaze.h"
|
||||
#include "Exceptions/MovementNotPossible.h"
|
||||
#include "Exceptions/UnkownAction.h"
|
||||
|
||||
using game::Player;
|
||||
using game::PositionVector;
|
||||
using game::Maze;
|
||||
using game::MazeParser;
|
||||
using game::Game;
|
||||
|
||||
using game_exceptions::MalformedMaze;
|
||||
using game_exceptions::UnkownAction;
|
||||
using game_exceptions::MovementNotPossible;
|
||||
|
||||
// Ein Programm, welches dir erlaubt ein Labyrinth zu erkunden mit 'w', 'a', 's', und 'd'.
|
||||
const vector<int> player_start_position = {4, 0};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Erstelle eine Variable, in der wir das eingelesene Labyrinth speichern
|
||||
Maze maze;
|
||||
|
||||
try
|
||||
{
|
||||
// Lese das Labyrinth ein
|
||||
maze = MazeParser::request_maze_from_user();
|
||||
// Erstelle eine Variable, in der wir das eingelesene Labyrinth speichern
|
||||
Game game = Game();
|
||||
|
||||
// Starte das Spiel
|
||||
game.run_game();
|
||||
}
|
||||
catch (...)
|
||||
catch (MalformedMaze& _)
|
||||
{
|
||||
// Das Labyrinth einlesen hat nicht geklappt. Gebe Fehlermeldung aus und beende das Programm.
|
||||
cout << "Fehler beim Einlesen des Labyrinths.\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lese die Startpositon des Spielers aus dem eingelesenen Labyrinth aus
|
||||
vector<int> player_start_position = maze.get_player_start_position();
|
||||
|
||||
// Erstelle einen Spieler mit der gegebenen start position
|
||||
Player player = Player(player_start_position[1], player_start_position[0]);
|
||||
|
||||
// Erstelle eine Variable für den Input
|
||||
char game_input;
|
||||
|
||||
// Durchlaufe die Hauptschleife des Spiels
|
||||
while (true)
|
||||
{
|
||||
// Zeige dem Spieler das Spielfeld
|
||||
maze.render(player);
|
||||
|
||||
// Kontrolliere, ob der Spieler an einem Geist gestorben ist
|
||||
if (maze.was_player_killed_by_ghost(player))
|
||||
{
|
||||
cout << "Sie haben einen Geist getroffen! Game Over!\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// Kontrolliere, ob der Spieler schon das Ziel erreicht hat
|
||||
if (maze.is_player_at_goal(player))
|
||||
{
|
||||
// Ziel erreicht! Herzlichen Glückwunsch!
|
||||
cout << "Ziel erreicht! Herzlichen Glueckwunsch!\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// Lese Eingabe des Spielers
|
||||
cin >> game_input;
|
||||
|
||||
// Erstelle einen Vector mit einer Bewegung von 0 und 0
|
||||
PositionVector movement_vector = PositionVector(0, 0);
|
||||
|
||||
// Kontrolliere, was der Spieler machen möchte. Speichere die erforderte Bewegung im Bewegungsvektor.
|
||||
// Schreibe nachrichten in die Konsole,
|
||||
// wenn nach Hilfe gefragt wird oder eine unbekannte Eingabe eingegeben wurde
|
||||
switch (game_input)
|
||||
{
|
||||
case 'w':
|
||||
movement_vector.update(0, -1);
|
||||
break;
|
||||
case 'a':
|
||||
movement_vector.update(-1, 0);
|
||||
break;
|
||||
case 's':
|
||||
movement_vector.update(0, 1);
|
||||
break;
|
||||
case 'd':
|
||||
movement_vector.update(1, 0);
|
||||
break;
|
||||
case 'h':
|
||||
// Schreibe hilfsreiche Tipps in die Konsole
|
||||
cout <<
|
||||
"Du wurdest von einem Zauberer in ein Labyrinth gesperrt, nachdem du seine Künste beleidigt hast.\n"
|
||||
<< "Er laesst dich leben, wenn du es schaffst den Ausgang (Z) zu finden. Solltest du keinen Erfolg haben, laesst er dich verhungern.\n"
|
||||
<< "Auf deinem Abenteuer wirst du dabei boesen Geistern (A) begegnen und mit Schluesseln (K) Tueren (T) aufschliessen.\n"
|
||||
<< "Bewege dich mit 'w', 'a', 's' und 'd'.\n";
|
||||
break;
|
||||
default:
|
||||
// Die gewollte Aktion kenne ich nicht. Schreibe eine Fehlernachricht in die Konsole
|
||||
cout << "Diese Eingabe kenne ich nicht. Gib 'h' ein, um eine Hilfe zu erhalten.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// Kontrolliere gewollte Bewegung und setze sie um.
|
||||
try
|
||||
{
|
||||
maze = player.move(maze, movement_vector);
|
||||
}
|
||||
catch (runtime_error& err)
|
||||
{
|
||||
// Diese Bewegung ist nicht möglich!
|
||||
// Gebe aus, warum.
|
||||
cout << err.what() << "\n";
|
||||
}
|
||||
}
|
||||
// Beende das Programm
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue