diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index bc20090..9784cb2 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1,12 +1,49 @@ #include "Entity.h" +#include "../Environment/Maze.h" namespace game { - Entity::Entity(PositionVector starting_position, char display_character): pos(starting_position), display_character(display_character){} + Entity::Entity(PositionVector starting_position, char display_character): pos(starting_position), display_character(display_character), move_left(true){} bool Entity::is_at_position(const PositionVector& position) const { return this->pos.eq(position); } + void Entity::tick(Maze& maze, const PositionVector& player_position){ + switch (this->display_character) { + case 'A': + // No thoughts, head empty :P + return; + case 'B': + this->handle_bowie(maze); + return; + case 'C': + this->handle_connelly(maze, player_position); + return; + default: + return; + } + } - void move(const Maze& maze, const PositionVector& player_position); + void Entity::handle_bowie(Maze& maze) { + PositionVector target_position = {this->pos.x, this->pos.y}; + if (this->move_left) + target_position.change_x(-1); + else + target_position.change_x(1); + if (maze.is_pos_free(target_position, false)) + this->pos = target_position; + else + this->move_left = !this->move_left; + } + + void Entity::handle_connelly(Maze& maze, const PositionVector& player_position) { + PositionVector diff = maze.get_distance_pos1_pos2(player_position, this->pos); + PositionVector normalized_diff = {diff.x, diff.y}; + normalized_diff.normalize(); + PositionVector target_position = {this->pos.x, this->pos.y}; + } + + char Entity::get_display_character() { + return this->display_character; + } } diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index d030223..36a40ca 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -1,5 +1,6 @@ #include "../Util/PositionVector.h" + #ifndef ENTITY_H #define ENTITY_H @@ -10,10 +11,15 @@ namespace game private: PositionVector pos; char display_character; + bool move_left; + + void handle_bowie(Maze& maze); + void handle_connelly(Maze& maze, const PositionVector& player_position); public: Entity(PositionVector starting_position, char display_character); - void move(const Maze& maze, const PositionVector& player_position); + void tick(Maze& maze, const PositionVector& player_position); bool is_at_position(const PositionVector& position) const; + char get_display_character(); }; } // game diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 9586aa2..ebec744 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -80,30 +80,25 @@ namespace game } } - GameState Player::handle_collisions(const GameState& prev_game_state, const Maze& maze) { + GameState Player::handle_collisions(const Game& game, const Maze& maze) { char field_at_pos = maze.get_field(this->get_pos()); // Game state sanity check - if (prev_game_state != GameState::RUNNING) - return prev_game_state; + if (game.get_state() != GameState::RUNNING) + return game.get_state(); - if (field_at_pos == '.') - return GameState::RUNNING; - switch (field_at_pos) { - case 'A': - case 'B': - case 'C': + if (field_at_pos == '.'){ + if (game.is_enemy_at_pos(this->get_pos())) return GameState::HIT_BY_GHOST; - break; - default: - break; + return GameState::RUNNING; } - return prev_game_state; + // You are not supposed to be here! + return game.get_state(); } - void Player::tick(const GameState& prev_game_state, Maze& maze) { + void Player::tick(const Game& game, Maze& maze) { this->handle_keys(maze); - this->handle_collisions(prev_game_state, maze); + this->handle_collisions(game, maze); } bool Player::has_key_available() const diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 97e134a..54addaa 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -9,6 +9,7 @@ using game::GameState; namespace game { class Maze; + class Game; /// Ein Spieler. /// Besitzt einen veränderbaren Positionsvektor @@ -32,7 +33,7 @@ namespace game /// Kontrolliere, ob der Spieler gerade in einem Geist steht /// @param maze Das Maze - GameState handle_collisions(const GameState& prev_game_state, const Maze& maze); + GameState handle_collisions(const Game& game, const Maze& maze); public: /// Ein Spieler. @@ -57,7 +58,7 @@ namespace game Maze handle_user_input(Maze& maze, const char& input); /// - void tick(const GameState& prev_game_state, Maze& maze); + void tick(const Game& game, Maze& maze); /// Check, if a player has at least one key /// @return If the player as an available key diff --git a/src/Environment/Game.cpp b/src/Environment/Game.cpp index e484e4f..b482a7f 100644 --- a/src/Environment/Game.cpp +++ b/src/Environment/Game.cpp @@ -12,14 +12,14 @@ using game_exceptions::MovementNotPossible; namespace game { - Game::Game(Maze& maze): maze(maze), player(0, 0), infomode_enabled(false), state(GameState::RUNNING) + Game::Game(Maze& maze): maze(maze), player(0, 0), infomode_enabled(false), state(GameState::RUNNING), enemies({}) { PositionVector player_start_position = this->maze.get_player_start_position(); this->player = Player(player_start_position); } - GameState Game::get_state() { + GameState Game::get_state() const { return this->state; } @@ -46,6 +46,13 @@ namespace game } } + bool Game::is_enemy_at_pos(const PositionVector& position) const{ + for (Entity e : this->enemies) + if (e.is_at_position(position)) + return true; + return false; + } + bool Game::should_end_game() { return this->state != GameState::RUNNING; } @@ -79,7 +86,12 @@ namespace game cout << err.what() << "\n"; } - this->player.tick(this->state, this->maze); + this->player.tick(*this, this->maze); + + for (Entity e : this->enemies) + e.tick(this->maze, this->player.get_pos()); + + this->player.tick(*this, this->maze); if (this->should_end_game()) return; diff --git a/src/Environment/Game.h b/src/Environment/Game.h index e53c965..78d6c49 100644 --- a/src/Environment/Game.h +++ b/src/Environment/Game.h @@ -1,6 +1,7 @@ #include "Maze.h" #include "../Entities/Player.h" #include "../Util/GameState.h" +#include "../Entities/Entity.h" #ifndef GAME_H #define GAME_H @@ -39,7 +40,9 @@ namespace game /// Kriege den aktuellen Status des Spiels /// @returns Den aktuellen Status - GameState get_state(); + GameState get_state() const; + + bool is_enemy_at_pos(const PositionVector& position) const ; }; } // game diff --git a/src/Environment/Maze.cpp b/src/Environment/Maze.cpp index 175aa15..9291c64 100644 --- a/src/Environment/Maze.cpp +++ b/src/Environment/Maze.cpp @@ -45,9 +45,14 @@ namespace game if (y == player.get_pos().y && x == player.get_pos().x) cout << "S"; else { - for(Entity e : entities) { - } - cout << field[y][x]; + bool an_enemy_is_at_this_position = false; + for (Entity e : entities) + if (e.is_at_position({x, y})) { + an_enemy_is_at_this_position = true; + cout << e.get_display_character(); + } + if (!an_enemy_is_at_this_position) + cout << field[y][x]; } cout << " "; } @@ -69,4 +74,20 @@ namespace game { return this->player_start_position; } + + PositionVector Maze::get_distance_pos1_pos2(const PositionVector& pos1, const PositionVector& pos2) { + int x_diff = pos1.x - pos2.x; + int y_diff = pos1.y - pos2.y; + return {x_diff, y_diff}; + } + + int Maze::calculate_steps(const PositionVector& target_position, PositionVector position, int steps) { + if (this->is_pos_free(position, false)) + return 999; + if (target_position.eq(position)) + return 0; + if (steps <= 0) + return 999; + vector i; + } } // game diff --git a/src/Environment/Maze.h b/src/Environment/Maze.h index 0770069..24f4f3a 100644 --- a/src/Environment/Maze.h +++ b/src/Environment/Maze.h @@ -57,6 +57,12 @@ namespace game /// Kriege die Startposition des Spielers /// @return Die Startposition des Spielers PositionVector get_player_start_position() const; + + /// Berrechne den Abstand zwischen zwei Vektoren + /// @return Der Abstand als Differenzvektor + PositionVector get_distance_pos1_pos2(const PositionVector& pos1, const PositionVector& pos2); + + int calculate_steps(const PositionVector& target_position, PositionVector position, int steps); }; } // game diff --git a/src/Util/MazeParser.cpp b/src/Util/MazeParser.cpp index 5c6785d..461d649 100644 --- a/src/Util/MazeParser.cpp +++ b/src/Util/MazeParser.cpp @@ -1,8 +1,10 @@ #include "MazeParser.h" #include "../Environment/Maze.h" #include "../Exceptions/MalformedMaze.h" +#include "../Entities/Entity.h" using game_exceptions::MalformedMaze; +using game::Entity; namespace game { @@ -33,12 +35,20 @@ namespace game return false; } + bool MazeParser::is_valid_enemy(const char& target) { + for (const char c : valid_enemies) + if (c == target) + return true; + return false; + } + Maze MazeParser::request_maze_from_user() { vector maze_size = request_numbers_from_user(2); char input; vector> field; + vector enemies; for (int y = 0; y < maze_size[0]; ++y) { @@ -49,14 +59,18 @@ namespace game if (!cin) throw MalformedMaze("Cin failed while reading chars!"); - // I don't think that this is needed. I doubt that the test check for this one ~Eric - //if (input == 'q') + // I don't think that this is needed. I doubt that they test the check for this one ~Eric + // if (input == 'q') // throw ExitGame("Schoenen Tag noch!"); if (!validate_maze_element(input)) throw MalformedMaze("The given input is not a valid element of a maze!"); - - row.push_back(input); + if (!is_valid_enemy(input)) + row.push_back(input); + else { + enemies.push_back(Entity({x, y}, input)); + row.push_back('.'); + } } field.push_back(row); @@ -64,6 +78,6 @@ namespace game vector player_start_pos = request_numbers_from_user(2); - return Maze(field, player_start_pos); + return Maze(field, player_start_pos, enemies); } // Beispieleingabe: `4 3 #.# #.K #T# #Z# 0 1` } // game diff --git a/src/Util/MazeParser.h b/src/Util/MazeParser.h index b0ccdd3..29c60a0 100644 --- a/src/Util/MazeParser.h +++ b/src/Util/MazeParser.h @@ -19,6 +19,7 @@ namespace game /// Erlaubte Zeichen in einem Labyrinth /// Ist eine Konstante, darf also in global scope static const vector valid_maze_elements = {'Z', '.', '#', 'A', 'K', 'T', 'B', 'C'}; + static const vector valid_enemies = {'A', 'B', 'C'}; static constexpr int MAX_MAZE_SIZE = 20; class Maze; @@ -35,6 +36,8 @@ namespace game /// @return Ob das gegebene Zeichen in einem Labyrinth vorkommen darf static bool validate_maze_element(const char& target); + static bool is_valid_enemy(const char& target); + public: /// Lese ein Labyrinth aus der Konsole /// @return Das Labyrinth diff --git a/src/Util/PositionVector.cpp b/src/Util/PositionVector.cpp index 25cfa9c..9c88d5d 100644 --- a/src/Util/PositionVector.cpp +++ b/src/Util/PositionVector.cpp @@ -14,6 +14,21 @@ namespace game this->y = y; } + void PositionVector::change_x(const int& amount) { + this->x += amount; + } + + void PositionVector::change_y(const int& amount) { + this->y += amount; + } + + void PositionVector::normalize() { + if (this->x < 0) + this->x *= -1; + if (this->y < 0) + this->y *= -1; + } + bool PositionVector::eq(const PositionVector& position) const { return this->x == position.x && this->y == position.y; } diff --git a/src/Util/PositionVector.h b/src/Util/PositionVector.h index 5057ff5..0fc0bc6 100644 --- a/src/Util/PositionVector.h +++ b/src/Util/PositionVector.h @@ -23,6 +23,11 @@ namespace game /// @param y Die neue 'Y'-Koordinate void update(const int& x, const int& y); + void change_x(const int& amount); + void change_y(const int& amount); + + void normalize(); + bool eq(const PositionVector& position)const ; }; } // game