From bc43cd157ad62be62c31a3058c538078e9305a9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=9F=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=94=D0=B0?=
 =?UTF-8?q?=D0=BD=D0=B8=D0=BB=D0=B0=20=D0=9C=D0=B8=D1=85=D0=B0=D0=B9=D0=BB?=
 =?UTF-8?q?=D0=BE=D0=B2=D0=B8=D1=87?= <dmpechenin@edu.hse.ru>
Date: Wed, 5 Mar 2025 20:49:44 +0300
Subject: [PATCH] Maze, room, IEntity, RoomSide were added + some fixes

---
 CMakeLists.txt                                |  2 ++
 source/Application/Application.cpp            |  2 +-
 source/Application/Application.h              |  3 +-
 source/BasicAbstractions/Font.h               |  2 +-
 .../IState.h                                  |  0
 .../IWindowKeeper.h                           |  6 ++--
 source/States/ChangeStateCommand.h            |  6 ++--
 source/States/ExitState/ExitState.h           |  2 +-
 source/States/GameState/Entities/IEntity.h    | 12 +++++++
 source/States/GameState/GameState.cpp         |  2 +-
 source/States/GameState/GameState.h           |  4 +--
 source/States/GameState/IPreparable.h         |  7 ++++
 source/States/GameState/Maze/Maze.cpp         |  6 ++++
 source/States/GameState/Maze/Maze.h           | 13 ++++++++
 source/States/GameState/Maze/Room.cpp         | 26 +++++++++++++++
 source/States/GameState/Maze/Room.h           | 25 +++++++++++++++
 source/States/GameState/Maze/RoomSide.cpp     |  7 ++++
 source/States/GameState/Maze/RoomSide.h       | 32 +++++++++++++++++++
 source/States/SelectState/SelectState.cpp     |  6 ++--
 source/States/SelectState/SelectState.h       |  8 ++---
 source/main.cpp                               |  3 +-
 21 files changed, 152 insertions(+), 22 deletions(-)
 rename source/{Application => BasicAbstractions}/IState.h (100%)
 rename source/{Application => BasicAbstractions}/IWindowKeeper.h (65%)
 create mode 100644 source/States/GameState/Entities/IEntity.h
 create mode 100644 source/States/GameState/IPreparable.h
 create mode 100644 source/States/GameState/Maze/Maze.cpp
 create mode 100644 source/States/GameState/Maze/Maze.h
 create mode 100644 source/States/GameState/Maze/Room.cpp
 create mode 100644 source/States/GameState/Maze/Room.h
 create mode 100644 source/States/GameState/Maze/RoomSide.cpp
 create mode 100644 source/States/GameState/Maze/RoomSide.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 67219d2..fd6f28c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,4 +12,6 @@ FetchContent_Declare(SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TA
 FetchContent_MakeAvailable(SFML)
 
 add_executable(${PROJECT_NAME} ${SOURCES})
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/source)
+
 target_link_libraries(${PROJECT_NAME} PRIVATE sfml-system sfml-window sfml-graphics)
\ No newline at end of file
diff --git a/source/Application/Application.cpp b/source/Application/Application.cpp
index b50721b..44cba1b 100644
--- a/source/Application/Application.cpp
+++ b/source/Application/Application.cpp
@@ -1,5 +1,5 @@
 #include "Application.h"
-#include <iostream> /// @todo избвится
+#include <iostream>
 
 void Application::apply_deffer_state_change() {
     if (m_ptr_state_next)
diff --git a/source/Application/Application.h b/source/Application/Application.h
index f70480f..dd0db81 100644
--- a/source/Application/Application.h
+++ b/source/Application/Application.h
@@ -1,6 +1,5 @@
 #pragma once
-#include "../States/SelectState/SelectState.h"
-#include "../Configuration.h"
+#include <States/SelectState/SelectState.h>
 
 class Application : public IStateManager {
 public:
diff --git a/source/BasicAbstractions/Font.h b/source/BasicAbstractions/Font.h
index 3f38a78..4fd6264 100644
--- a/source/BasicAbstractions/Font.h
+++ b/source/BasicAbstractions/Font.h
@@ -1,5 +1,5 @@
 #pragma once
-#include "../Configuration.h"
+#include <Configuration.h>
 
 class MyFont {
 public:
diff --git a/source/Application/IState.h b/source/BasicAbstractions/IState.h
similarity index 100%
rename from source/Application/IState.h
rename to source/BasicAbstractions/IState.h
diff --git a/source/Application/IWindowKeeper.h b/source/BasicAbstractions/IWindowKeeper.h
similarity index 65%
rename from source/Application/IWindowKeeper.h
rename to source/BasicAbstractions/IWindowKeeper.h
index 215a3bd..16b5ee0 100644
--- a/source/Application/IWindowKeeper.h
+++ b/source/BasicAbstractions/IWindowKeeper.h
@@ -1,9 +1,11 @@
 #pragma once
-#include <SFML/Graphics.hpp>
+#include <Configuration.h>
 
 class IWindowKeeper {
 public:
-    IWindowKeeper(const sf::VideoMode& video_mode, const sf::String& window_title) : m_window(video_mode, window_title) {}
+    IWindowKeeper(const sf::VideoMode& video_mode, const sf::String& window_title) : m_window(video_mode, window_title) {
+        m_window.setFramerateLimit(config::FRAME_RATE_LIMIT);
+    }
     virtual ~IWindowKeeper() = default;
 protected:
     virtual void event_handling() = 0;
diff --git a/source/States/ChangeStateCommand.h b/source/States/ChangeStateCommand.h
index e2f3e0e..a0927c8 100644
--- a/source/States/ChangeStateCommand.h
+++ b/source/States/ChangeStateCommand.h
@@ -1,7 +1,7 @@
 #pragma once
-#include "../BasicAbstractions/Command.h"
-#include "../Application/IState.h"
-#include "ExitState/ExitState.h"
+#include <BasicAbstractions/Command.h>
+#include <BasicAbstractions/IState.h>
+#include <States/ExitState/ExitState.h>
 
 struct ChangeStateCommand : ISelectCommand {
     explicit ChangeStateCommand(IStateManager& state_manager) : m_state_manager(state_manager) {}
diff --git a/source/States/ExitState/ExitState.h b/source/States/ExitState/ExitState.h
index 22ce415..0a97601 100644
--- a/source/States/ExitState/ExitState.h
+++ b/source/States/ExitState/ExitState.h
@@ -1,5 +1,5 @@
 #pragma once
-#include "../../Application/IState.h"
+#include <BasicAbstractions/IState.h>
 
 struct ExitState : IState {
     using IState::IState;
diff --git a/source/States/GameState/Entities/IEntity.h b/source/States/GameState/Entities/IEntity.h
new file mode 100644
index 0000000..8f32b18
--- /dev/null
+++ b/source/States/GameState/Entities/IEntity.h
@@ -0,0 +1,12 @@
+#pragma once
+#include <States/GameState/IPreparable.h>
+#include <States/GameState/Maze/Room.h>
+
+class IEntity : public IPreparable {
+public:
+    void set_location(Room* ptr_room) { m_ptr_room = ptr_room; }
+    [[nodiscard]] Room* get_location() const { return m_ptr_room; }
+    ~IEntity() override = default;
+protected:
+    Room* m_ptr_room = nullptr;
+};
\ No newline at end of file
diff --git a/source/States/GameState/GameState.cpp b/source/States/GameState/GameState.cpp
index 549da1c..8aec679 100644
--- a/source/States/GameState/GameState.cpp
+++ b/source/States/GameState/GameState.cpp
@@ -1,6 +1,6 @@
 #include "GameState.h"
 #include <iostream> /// @todo remove it
-#include "../ExitState/ExitState.h"
+#include <States/ExitState/ExitState.h>
 
 bool GameState::do_step() {
     std::cout << "Game state" << std::endl;
diff --git a/source/States/GameState/GameState.h b/source/States/GameState/GameState.h
index e1fac84..aa1d5ca 100644
--- a/source/States/GameState/GameState.h
+++ b/source/States/GameState/GameState.h
@@ -1,6 +1,6 @@
 #pragma once
-#include "../../Application/IState.h"
-#include "../../Application/IWindowKeeper.h"
+#include <BasicAbstractions/IState.h>
+#include <BasicAbstractions/IWindowKeeper.h>
 
 struct GameState : IState, IWindowKeeper {
     explicit GameState(IStateManager& state_manager, const sf::VideoMode& video_mode, const sf::String& window_title) : IState(state_manager), IWindowKeeper(video_mode, window_title) {}
diff --git a/source/States/GameState/IPreparable.h b/source/States/GameState/IPreparable.h
new file mode 100644
index 0000000..b350000
--- /dev/null
+++ b/source/States/GameState/IPreparable.h
@@ -0,0 +1,7 @@
+#pragma once
+#include <BasicAbstractions/IDrawable.h>
+
+struct IPreparable : IDrawable {
+    virtual void prepare_for_drawing() = 0;
+    ~IPreparable() override = default;
+};
\ No newline at end of file
diff --git a/source/States/GameState/Maze/Maze.cpp b/source/States/GameState/Maze/Maze.cpp
new file mode 100644
index 0000000..fc1be98
--- /dev/null
+++ b/source/States/GameState/Maze/Maze.cpp
@@ -0,0 +1,6 @@
+#include <States/GameState/Maze/Maze.h>
+
+void Maze::draw_into(sf::RenderWindow& window) const {
+    for (const auto& room : m_rooms)
+        room->draw_into(window);
+}
\ No newline at end of file
diff --git a/source/States/GameState/Maze/Maze.h b/source/States/GameState/Maze/Maze.h
new file mode 100644
index 0000000..a188a84
--- /dev/null
+++ b/source/States/GameState/Maze/Maze.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <States/GameState/Maze/Room.h>
+
+#include <vector>
+
+class Maze : public IDrawable {
+public:
+    explicit Maze(std::vector<std::unique_ptr<Room>> rooms) : m_rooms(std::move(rooms)) {}
+    void draw_into(sf::RenderWindow& window) const override;
+private:
+    std::vector<std::unique_ptr<Room>> m_rooms;
+};
\ No newline at end of file
diff --git a/source/States/GameState/Maze/Room.cpp b/source/States/GameState/Maze/Room.cpp
new file mode 100644
index 0000000..4f8964a
--- /dev/null
+++ b/source/States/GameState/Maze/Room.cpp
@@ -0,0 +1,26 @@
+#include <States/GameState/Maze/Room.h>
+
+Room::Room(float size) : m_rectangle({size, size}) {
+    m_rectangle.setOrigin(size/2, size/2);
+}
+
+void Room::set_side(const Direction side, std::unique_ptr<IRoomSide>&& ptr_side) {
+    if (side == INVALID) throw std::invalid_argument("Invalid direction");
+    m_sides[side] = std::move(ptr_side);
+}
+
+Room::Direction Room::get_direction(const IRoomSide* ptr_side) const {
+    if (m_sides[LEFT].get() == ptr_side) return LEFT;
+    if (m_sides[RIGHT].get() == ptr_side) return RIGHT;
+    if (m_sides[UP].get() == ptr_side) return UP;
+    if (m_sides[DOWN].get() == ptr_side) return DOWN;
+    return INVALID;
+}
+
+void Room::draw_into(sf::RenderWindow& window) const {
+    window.draw(m_rectangle);
+    for (auto& side : m_sides) {
+        side->draw_into(window);
+    }
+}
+
diff --git a/source/States/GameState/Maze/Room.h b/source/States/GameState/Maze/Room.h
new file mode 100644
index 0000000..db04902
--- /dev/null
+++ b/source/States/GameState/Maze/Room.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <States/GameState/IPreparable.h>
+#include <States/GameState/Maze/RoomSide.h>
+
+#include <array>
+
+struct IRoomSide;
+
+class Room: public IDrawable {
+public:
+    enum Direction { INVALID = -1, LEFT, RIGHT, UP, DOWN };
+    explicit Room(float size);
+    float get_size() const { return m_rectangle.getSize().x; }
+    void set_position(const sf::Vector2f pos) { m_rectangle.setPosition(pos); }
+    sf::Vector2f get_position() const { return m_rectangle.getPosition(); }
+    void set_side(Direction side, std::unique_ptr<IRoomSide>&& ptr_side);
+    IRoomSide* get_side(const Direction side) const { return m_sides[side].get(); }
+    Direction get_direction(const IRoomSide* ptr_side) const;
+    void draw_into(sf::RenderWindow& window) const override;
+private:
+    sf::RectangleShape m_rectangle;
+    std::array<std::unique_ptr<IRoomSide>, 4> m_sides;
+};
+
diff --git a/source/States/GameState/Maze/RoomSide.cpp b/source/States/GameState/Maze/RoomSide.cpp
new file mode 100644
index 0000000..48f6d5c
--- /dev/null
+++ b/source/States/GameState/Maze/RoomSide.cpp
@@ -0,0 +1,7 @@
+#include <States/GameState/Entities/IEntity.h>
+
+void Pass::enter(IEntity* entity) const {
+    if (entity->get_location() == &m_room1)
+        entity->set_location(&m_room2);
+    else entity->set_location(&m_room1);
+}
\ No newline at end of file
diff --git a/source/States/GameState/Maze/RoomSide.h b/source/States/GameState/Maze/RoomSide.h
new file mode 100644
index 0000000..0c2dca7
--- /dev/null
+++ b/source/States/GameState/Maze/RoomSide.h
@@ -0,0 +1,32 @@
+#pragma once
+#include <States/GameState/IPreparable.h>
+
+class IEntity;
+class Room;
+
+struct IRoomSide : IPreparable {
+    virtual void enter(IEntity* entity) const = 0;
+    ~IRoomSide() override = default;
+};
+
+class Pass : public IRoomSide {
+public:
+    explicit Pass(Room& room1, Room& room2) : m_room1(room1), m_room2(room2) {}
+    void enter(IEntity* entity) const override;
+    void draw_into(sf::RenderWindow& window) const override {}
+    void prepare_for_drawing() override {}
+private:
+    Room& m_room1;
+    Room& m_room2;
+};
+
+class Wall : public IRoomSide {
+public:
+    explicit Wall(Room& room) : m_room(room) {}
+    void enter(IEntity* entity) const override {}
+    void draw_into(sf::RenderWindow& window) const override { window.draw(m_line, 2, sf::Lines); }
+    void prepare_for_drawing() override {} /// @todo разобраться, что тут делать
+private:
+    Room& m_room;
+    sf::Vertex m_line[2];
+};
\ No newline at end of file
diff --git a/source/States/SelectState/SelectState.cpp b/source/States/SelectState/SelectState.cpp
index 2d57798..2661e9d 100644
--- a/source/States/SelectState/SelectState.cpp
+++ b/source/States/SelectState/SelectState.cpp
@@ -1,7 +1,6 @@
 #include "SelectState.h"
-#include "../ChangeStateCommand.h"
-#include "../../Configuration.h"
-#include "../../BasicAbstractions/Font.h"
+#include <States/ChangeStateCommand.h>
+#include <BasicAbstractions/Font.h>
 
 void Button::set(const sf::Vector2f pos, const sf::Vector2f size, const std::string& text, const size_t font_size, std::unique_ptr<ISelectCommand> ptr_command) {
     m_rectangle.setSize(size);
@@ -102,7 +101,6 @@ void SelectState::render() {
 }
 
 bool SelectState::do_step() {
-    m_window.setFramerateLimit(config::FRAME_RATE_LIMIT);
     while (m_window.isOpen()) {
         event_handling();
         update();
diff --git a/source/States/SelectState/SelectState.h b/source/States/SelectState/SelectState.h
index 063d351..4b0dc6a 100644
--- a/source/States/SelectState/SelectState.h
+++ b/source/States/SelectState/SelectState.h
@@ -1,8 +1,8 @@
 #pragma once
-#include "../../Application/IState.h"
-#include "../../Application/IWindowKeeper.h"
-#include "../../BasicAbstractions/IDrawable.h"
-#include "../../BasicAbstractions/Command.h"
+#include <BasicAbstractions/IState.h>
+#include <BasicAbstractions/IWindowKeeper.h>
+#include <BasicAbstractions/IDrawable.h>
+#include <BasicAbstractions/Command.h>
 
 class Button: public IDrawable {
 public:
diff --git a/source/main.cpp b/source/main.cpp
index 9859de7..ee0bc6a 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -1,4 +1,5 @@
-#include "Application/Application.h"
+#include <Application/Application.h>
+
 int main() {
     Application app;
     return app.run();
-- 
GitLab