diff --git a/CMakeLists.txt b/CMakeLists.txt
index 67219d20ff7db10094da114b45cf249cd485aaf3..fd6f28cf7f56661c8faf2140db57a32ecde5a5e0 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 b50721b48fdb185b4079c5f36ba4feab3f66cc1d..44cba1bee6c769f80eaf3d667e76f94c003072c0 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 f70480f7cbe73d9d2163a19d5a108ec8c7bb2dcb..dd0db81d127f82fcf7a3ecfb05e08afb1317ce0e 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 3f38a7809dc23832af9d23e1eaa864d8a7d24b81..4fd6264e204ab1865cf71b6823b3a6536de733fb 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 215a3bd8e51542f7762fd25bb444a08f560fe259..16b5ee0d2308654c418870dcd254b8ffaf1aaf82 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 e2f3e0e7127b04a541d70af2665e92639f20e78d..a0927c8f91536ac0cdedea9edacfb71815f5aeae 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 22ce415cccb9648efc109dcd25aba17605315fcb..0a976014e804bcb3c06ebc3278962b9d235a36d6 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 0000000000000000000000000000000000000000..8f32b18b25c5a9669f7a8cf132d56055a5e8f903
--- /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 549da1c8cdee8279ab8563a4759ed91b8a36afa8..8aec6792c3c108d9275c2c895d8d2655d17a3176 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 e1fac84613950223566127ee03dac5f5f47361c7..aa1d5ca80235302287185188bf758a7054ea1efe 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 0000000000000000000000000000000000000000..b35000096357eec99177a60010811fda75f74f45
--- /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 0000000000000000000000000000000000000000..fc1be98db4b3dc4b1a5adb55b022b849a017ff61
--- /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 0000000000000000000000000000000000000000..a188a840b6153f61bc6fd0ac7c7b47eceb5a2da6
--- /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 0000000000000000000000000000000000000000..4f8964a87bf653b267892c3792a4fbe2e863efef
--- /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 0000000000000000000000000000000000000000..db04902a012fc5c14a93afb5305acbce888a6265
--- /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 0000000000000000000000000000000000000000..48f6d5c19412a64918598b46b4419e5bcf2d09da
--- /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 0000000000000000000000000000000000000000..0c2dca7bc736654e04b34f2ee2c89e7e73a0bd4d
--- /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 2d577984536365f5c9f7f17754b6864df9698fce..2661e9d76b27fe9e25a76615c9a615ec028feaeb 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 063d351b457110979831466cd74f982435ecda28..4b0dc6ae0b1f2d900f8f2463127620e29814bea4 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 9859de70f6e0f2ad739428ad3799d19c2e79ae46..ee0bc6a81802f056c1fdc991b108a4ac6771a08c 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();