diff --git a/source/application/App/Application.h b/source/application/App/Application.h
index e2ad97f039730e116cbd8a4784f69f9954e46852..d8c0124f5d12df093cefaa247696f0258b22f9ba 100644
--- a/source/application/App/Application.h
+++ b/source/application/App/Application.h
@@ -10,6 +10,7 @@ class Application : public IStateManager {
 public:
     Application();
     int run();
+    ~Application() = default;
 
 private:
     void set_next_state(std::unique_ptr<IState>&& ptr_state) override;
diff --git a/source/application/BobBuilder/GameBuilders.cpp b/source/application/BobBuilder/GameBuilders.cpp
index d2232a1bfd13c27e2542f6145357288f52446648..653f125ccecbd8ef42beaec35b88bb91dbc45e19 100644
--- a/source/application/BobBuilder/GameBuilders.cpp
+++ b/source/application/BobBuilder/GameBuilders.cpp
@@ -7,25 +7,24 @@ CommonBuilder::CommonBuilder(float width, float height, float room_size) :
 }
 
 void CommonBuilder::create_context(float dynamic_objects_ratio) {
-    GameContext context;
     std::vector<Room*> empty_rooms_buffer;
     for (auto& row : m_rooms)
         for (auto& room : row)
-            empty_rooms_buffer.emplace_back(room);
-
+            if (room != nullptr)
+                empty_rooms_buffer.emplace_back(room);
     float id = std::rand() % empty_rooms_buffer.size();
-    context.pacman.set_location(empty_rooms_buffer[id]);
+    m_context.pacman.set_location(empty_rooms_buffer[id]);
     auto it = std::next(empty_rooms_buffer.begin(), id);
     empty_rooms_buffer.erase(it);
+    //@todo располагать врагов
 
-
+    //располагаем еду
     for (auto it : empty_rooms_buffer) {
         auto food = std::make_unique<Food>();
         food->set_location(it);
-        context.static_objects.emplace_back(std::move(food));
+        m_context.static_objects.emplace_back(std::move(food));
     }
     empty_rooms_buffer.clear();
-    m_context = std::move(context);
 }
 
 void CommonBuilder::create_state(IStateManager &state_manager, const sf::VideoMode &mode, const std::string &window_title) {
@@ -36,7 +35,7 @@ void CommonBuilder::set_all_to_state() {
     std::vector<Room*> rooms;
     for (auto& row : m_rooms)
         for (auto& col : row)
-            rooms.push_back(col);
+            rooms.emplace_back(col);
     Maze maze(rooms);
     m_game_state->set_maze(std::move(maze));
     m_game_state->set_context(std::move(m_context));
@@ -55,10 +54,10 @@ void SimpleBuilder::create_rooms() {
         std::vector<Room*> row_vec;
         for (size_t col = 0; col < cols * room_size; col += room_size) {
             Room* room = new Room(m_room_size);
-            room->set_position(sf::Vector2f {col + left_pos.x, row + left_pos.y});
-            row_vec.push_back(std::move(room));
+            room->set_position({col + left_pos.x, row + left_pos.y});
+            row_vec.emplace_back(room);
         }
-        m_rooms.push_back(std::move(row_vec));
+        m_rooms.emplace_back(std::move(row_vec));
     }
 }
 
diff --git a/source/application/Context/Context.cpp b/source/application/Context/Context.cpp
index 2757e87538cb91183250ac7a0e3e00455f54fef3..fe23398a7d68299620dc18bd3ca36791015ef4e1 100644
--- a/source/application/Context/Context.cpp
+++ b/source/application/Context/Context.cpp
@@ -4,6 +4,7 @@ GameContext GameContext::clone() {
     GameContext context;
     context.pacman = pacman;
     context.state = state;
+
     for (auto& obj: static_objects) {
         context.static_objects.emplace_back(obj->clone());
     }
@@ -13,11 +14,17 @@ GameContext GameContext::clone() {
     return context;
 }
 
+//@todo
 void ContextManager::restore_previous_context() {
     if (m_history.size() == 1) {
         m_initial_context = m_history.top().clone();
         return;
     }
     m_initial_context = std::move(m_history.top());
-    m_history.pop();
-}
\ No newline at end of file
+}
+
+void ContextManager::reset(GameContext &&context) {
+    while (!m_history.empty()) m_history.pop();
+    m_initial_context = context.clone();
+    m_history.emplace(m_initial_context.clone());
+}
diff --git a/source/application/Context/Context.h b/source/application/Context/Context.h
index 096ffba785abc248e000e8aa7d79311ed28e80e7..456d2e396e8c3f5a4c071a57b7eaa194f52746c4 100644
--- a/source/application/Context/Context.h
+++ b/source/application/Context/Context.h
@@ -19,7 +19,7 @@ class ContextManager {
 public:
     void save_current_context() { m_history.push(m_initial_context.clone()); };
     void restore_previous_context();
-    void reset(GameContext&& context) { m_initial_context = std::move(context); };
+    void reset(GameContext&& context);
     GameContext& get_current_context() { return m_initial_context; };
 private:
     GameContext m_initial_context;
diff --git a/source/application/Drawable/Entity/IEntity.cpp b/source/application/Drawable/Entity/IEntity.cpp
index 966fcad5aef7e35f4cb6ba2e07ab967d512d3f91..ab32bca22cc688da21afa05afcfce018067ffbc4 100644
--- a/source/application/Drawable/Entity/IEntity.cpp
+++ b/source/application/Drawable/Entity/IEntity.cpp
@@ -20,8 +20,18 @@ void Food::prepare_for_drawing() {
     m_shape.setPosition(m_ptr_room->get_position());
 }
 
-void Food::draw_into(sf::RenderWindow &window) {
-    prepare_for_drawing();
+std::unique_ptr<IGameEvent> Enemy::accept(IVisitor* ptr_visitor) {
+    return ptr_visitor->visit(this);
+}
+
+std::unique_ptr<IGameEvent> Food::accept(IVisitor* ptr_visitor) {
+    return ptr_visitor->visit(this);
+}
+
+
+void Food::draw_into(sf::RenderWindow& window) {
+    m_shape.setPosition(m_ptr_room->get_position());
+    //из класса Room: sf::Vector2f get_position() { return m_rectangle.getPosition(); }
     window.draw(m_shape);
 }
 
@@ -51,5 +61,4 @@ void Enemy::action() {
     auto direction = static_cast<Room::Direction>(rand() % 4);
     m_ptr_room->get_side(direction)->enter(this);
     m_clock.restart();
-
 }
\ No newline at end of file
diff --git a/source/application/Drawable/Entity/IEntity.h b/source/application/Drawable/Entity/IEntity.h
index f833764fda5a5fdc600c7ecafb47f35330772e3b..6a83d0970b5d9a76df4b1d088ed9c45e8ac6a69a 100644
--- a/source/application/Drawable/Entity/IEntity.h
+++ b/source/application/Drawable/Entity/IEntity.h
@@ -1,8 +1,18 @@
 #pragma once
 
 #include "../IDrawable.h"
+#include "../../Event/IGameEvent.h"
 
 class Room;
+class Food;
+class Enemy;
+
+class IVisitor {
+public:
+    virtual std::unique_ptr<IGameEvent> visit(Food* ptr_entity) = 0;
+    virtual std::unique_ptr<IGameEvent> visit(Enemy* ptr_entity) = 0;
+
+};
 
 class IEntity: public IPreparable {
 public:
@@ -12,12 +22,17 @@ protected:
     Room* m_ptr_room;
 };
 
-class IStaticEntity : public IEntity {
+class IVisitable {
+public:
+    virtual std::unique_ptr<IGameEvent> accept(IVisitor* ptr_visitor) = 0;
+};
+
+class IStaticEntity : public IEntity, public IVisitable {
 public:
     virtual std::unique_ptr<IStaticEntity> clone() const = 0;
 };
 
-class IDynamicEntity: public IEntity {
+class IDynamicEntity: public IEntity, public IVisitable {
 public:
     virtual void action() = 0;
     virtual std::unique_ptr<IDynamicEntity> clone() const = 0;
@@ -30,6 +45,8 @@ public:
     void action() override;
     void prepare_for_drawing() override;
     std::unique_ptr<IDynamicEntity> clone() const override;
+    std::unique_ptr<IGameEvent> accept(IVisitor* ptr_visitor) override;
+    ~Enemy() override {};
 private:
     sf::CircleShape m_shape;
     sf::Clock m_clock;
@@ -41,6 +58,8 @@ public:
     void draw_into(sf::RenderWindow& window) override;
     void prepare_for_drawing() override;
     std::unique_ptr<IStaticEntity>  clone() const override;
+    std::unique_ptr<IGameEvent> accept(IVisitor* ptr_visitor) override;
+    ~Food() override {};
 private:
     sf::CircleShape m_shape;
 };
\ No newline at end of file
diff --git a/source/application/Drawable/Entity/Pacman.cpp b/source/application/Drawable/Entity/Pacman.cpp
index 5b584bbff29cae40922d0485df97830d01d7a64e..e20ab2d1667b382f7c7750d37a7e311ee6dc24cf 100644
--- a/source/application/Drawable/Entity/Pacman.cpp
+++ b/source/application/Drawable/Entity/Pacman.cpp
@@ -15,6 +15,16 @@ void Pacman::prepare_for_drawing() {
     m_shape.setPosition(m_ptr_room->get_position());
 }
 
+std::unique_ptr<IGameEvent> Pacman::visit(Food *ptr_food) {
+    if (ptr_food->get_location() != this->get_location()) return {};
+    return std::make_unique<DeleteStaticEntity>(ptr_food);
+}
+
+std::unique_ptr<IGameEvent> Pacman::visit(Enemy *ptr_enemy) {
+    if (ptr_enemy->get_location() != this->get_location()) return {};
+    return std::make_unique<LostGame>();
+}
+
 void Pacman::draw_into(sf::RenderWindow &window) {
     prepare_for_drawing();
     window.draw(m_shape);
diff --git a/source/application/Drawable/Entity/Pacman.h b/source/application/Drawable/Entity/Pacman.h
index 445d516a46d152994ec0d98f352a6ac57e319bdb..8e5f5f693bb16e60581e4449327a33b80d86e7fd 100644
--- a/source/application/Drawable/Entity/Pacman.h
+++ b/source/application/Drawable/Entity/Pacman.h
@@ -3,12 +3,15 @@
 #include "IEntity.h"
 #include "../Maze/Maze.h"
 
-class Pacman : public IEntity {
+class Pacman : public IEntity, public IVisitor {
 public:
     Pacman();
     void move(Room::Direction direction);
     void prepare_for_drawing() override;
     void draw_into(sf::RenderWindow& window) override;
+    std::unique_ptr<IGameEvent> visit(Food* ptr_entity) override;
+    std::unique_ptr<IGameEvent> visit(Enemy* ptr_entity) override;
+    ~Pacman() override {};
 private:
     sf::CircleShape m_shape;
 };
\ No newline at end of file
diff --git a/source/application/Drawable/Maze/Maze.cpp b/source/application/Drawable/Maze/Maze.cpp
index 23c2b15b8268ea0a3d44580640d4d3022fa05b75..a8aba2ec0b8bbd63d2dbdf4a22f646aee93c0684 100644
--- a/source/application/Drawable/Maze/Maze.cpp
+++ b/source/application/Drawable/Maze/Maze.cpp
@@ -17,10 +17,11 @@ Room::Direction Room::get_direction(IRoomSide* ptr_side) {
     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;
-    else return INVALID;
+    return INVALID;
 }
 
 void Room::draw_into(sf::RenderWindow& window) {
+    window.draw(m_rectangle);
     for (const auto& side : m_sides) {
         side->draw_into(window);
     }
diff --git a/source/application/Event/IGameEvent.cpp b/source/application/Event/IGameEvent.cpp
index acd31bc397a06bb5d4dd3d688c8a48c2c71ed653..53101ecc7be613a32d84ea4a046ee13be416987d 100644
--- a/source/application/Event/IGameEvent.cpp
+++ b/source/application/Event/IGameEvent.cpp
@@ -5,10 +5,16 @@ void LostGame::handle(GameContext context) {
     context.state = GameContext::LOST;
 }
 
-void DeleteStaticEntity::handle(GameContext context) {
-    context.static_objects.erase(m_ptr_entity);
+void DeleteStaticEntity::handle(GameContext* context) {
+    auto it = std::find_if(context->static_objects.begin(), context->static_objects.end(),
+                           [this](const std::unique_ptr<IStaticEntity>& ptr) { return ptr.get() == m_ptr_entity; });
+    context->static_objects.erase(it);
 }
 
-void WinGame::handle(GameContext context) {
-    context.state = GameContext::WIN;
+DeleteStaticEntity::DeleteStaticEntity(IStaticEntity* ptr_entity) :
+        m_ptr_entity(ptr_entity) {
+}
+
+void WinGame::handle(GameContext* context) {
+    context->state = GameContext::WIN;
 }
\ No newline at end of file
diff --git a/source/application/Event/IGameEvent.h b/source/application/Event/IGameEvent.h
index 326eaabaa36197e0d9d49bc05be92df688b7b434..ea042600c1c63eb42a1d0930a6fd4cb3e18bf3e4 100644
--- a/source/application/Event/IGameEvent.h
+++ b/source/application/Event/IGameEvent.h
@@ -24,8 +24,8 @@ public:
 
 class DeleteStaticEntity : public IGameEvent {
 public:
-    DeleteStaticEntity(std::list<std::unique_ptr<IStaticEntity>>::iterator ptr_entity) : m_ptr_entity(ptr_entity) {};
-    void handle(GameContext context) override;
+    DeleteStaticEntity(IStaticEntity* ptr_entity);
+    void handle(GameContext* context) override;
 private:
-    std::list<std::unique_ptr<IStaticEntity>>::iterator m_ptr_entity;
+    IStaticEntity* m_ptr_entity;
 };
diff --git a/source/application/State/GameState.cpp b/source/application/State/GameState.cpp
index d87550d3831bc803f6243e7f57766a28a9b0ec5d..bab1573444a092463d3fd4b422d16a50b986b09b 100644
--- a/source/application/State/GameState.cpp
+++ b/source/application/State/GameState.cpp
@@ -1,7 +1,7 @@
 #include "GameState.h"
 #include "SelectState.h"
 #include "../../../workdir/config.h"
-
+#include "../Drawable/Entity/IEntity.h"
 GameState::GameState(IStateManager &state_manager, const sf::VideoMode &video_mode, const std::string &window_title) :
         IState(state_manager), IWindowKeeper(config::GAME_VIDEO_MODE, window_title){ }
 
@@ -23,45 +23,47 @@ void GameState::event_handling() {
 void GameState::process_key_pressed(sf::Keyboard::Key code) {
     switch (code) {
         case sf::Keyboard::W:
-            m_context_manager.save_current_context();
             m_context_manager.get_current_context().pacman.move(Room::UP);
             break;
         case sf::Keyboard::S:
-            m_context_manager.save_current_context();
             m_context_manager.get_current_context().pacman.move(Room::DOWN);
             break;
         case sf::Keyboard::A:
-            m_context_manager.save_current_context();
             m_context_manager.get_current_context().pacman.move(Room::LEFT);
             break;
         case sf::Keyboard::D:
-            m_context_manager.save_current_context();
             m_context_manager.get_current_context().pacman.move(Room::RIGHT);
             break;
     }
+}
 
-};
 void GameState::update() {
+    std::vector<std::unique_ptr<IGameEvent>> game_events;
     if (m_context_manager.get_current_context().state != GameContext::INGAME) return;
-
     GameContext& context = m_context_manager.get_current_context();
-    for (auto& entity : context.dynamic_objects)
-        entity->action();
-    for (auto it = context.static_objects.begin(); it != context.static_objects.end(); ++it) {
-        if (context.pacman.get_location() == (*it)->get_location()) {
-            m_events.emplace_back(std::move(std::make_unique<DeleteStaticEntity>(it)));
-        }
+    for (auto& entity_ptr : context.dynamic_objects) {
+        entity_ptr->action();
+        IVisitor* ptr_visitor = &(context.pacman);
+        game_events.emplace_back(entity_ptr->accept(ptr_visitor));
+    }
+    for (auto& static_ptr : context.static_objects) {
+        IVisitor* ptr_visitor = &(context.pacman);
+        auto ptr_event = static_ptr->accept(ptr_visitor);
+        if (ptr_event)
+            game_events.emplace_back(std::move(ptr_event));
     }
-
     for (auto it = context.dynamic_objects.begin(); it != context.dynamic_objects.end(); ++it) {
         if (context.pacman.get_location() == (*it)->get_location()) {
-            m_events.emplace_back(std::move(std::make_unique<LostGame>()));
+            game_events.emplace_back(std::move(std::make_unique<LostGame>()));
         }
     }
-
+    for (int i = 0; i < game_events.size(); i++) {
+        game_events[i]->handle(&m_context_manager.get_current_context());
+    }
     if (context.static_objects.empty()) {
-        m_events.emplace_back(std::move(std::make_unique<WinGame>()));
+        game_events.emplace_back(std::move(std::make_unique<WinGame>()));
     }
+    game_events.clear();
 }
 
 void GameState::render() {
@@ -77,13 +79,12 @@ void GameState::render() {
             m_window.clear(config::GAME_COLOR_BACKGROUND_WIN);
     }
     m_maze.draw_into(m_window);
-    for (auto& el: context.static_objects) {
-        el->draw_into(m_window);
+    context.pacman.draw_into(m_window);
+    for (auto& obj :  context.static_objects) {
+        obj->draw_into(m_window);
     }
 
 
-    context.pacman.draw_into(m_window);
-
     for (auto& el : context.dynamic_objects)
         el->draw_into(m_window);
     m_window.display();
@@ -97,6 +98,5 @@ bool GameState::do_step() {
 }
 
 void GameState::set_context(GameContext&& context) {
-    m_context_manager.save_current_context();
     m_context_manager.reset(std::move(context));
 }
\ No newline at end of file