From ff5012dce6bf355f58ba9352206e20da9c1e716d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A3=D1=88=D0=BA=D0=BE=D0=B2=D0=B0=20=D0=94=D0=B8=D0=B0?=
 =?UTF-8?q?=D0=BD=D0=B0=20=D0=9F=D0=B5=D1=82=D1=80=D0=BE=D0=B2=D0=BD=D0=B0?=
 <dpushkova@edu.hse.ru>
Date: Thu, 6 Mar 2025 08:22:54 +0000
Subject: [PATCH] created hardLevel, texture for food and Pacman

---
 CMakeLists.txt                                |   3 +-
 source/application/App/Application.cpp        |   3 +-
 source/application/App/Application.h          |   2 +-
 .../application/BobBuilder/GameBuilders.cpp   |  95 +++++++++++++++++-
 source/application/Context/Context.cpp        |   2 +-
 source/application/Context/Context.h          |   7 +-
 .../application/Drawable/DrawMenu/Font/Font.h |   2 +-
 .../Drawable/DrawMenu/Menu/Menu.cpp           |   2 +-
 .../application/Drawable/Entity/IEntity.cpp   |  18 ++--
 source/application/Drawable/Entity/IEntity.h  |   9 +-
 .../application/Drawable/Entity/MyTexture.cpp |  28 ++++++
 .../application/Drawable/Entity/MyTexture.h   |  35 +++++++
 source/application/Drawable/Entity/Pacman.cpp |  19 ++--
 source/application/Drawable/Entity/Pacman.h   |   6 +-
 source/application/Drawable/Maze/Maze.h       |   3 +-
 .../SelectCommand/ISelectCommand.cpp          |   2 -
 source/application/State/GameState.cpp        |  33 +++---
 source/application/State/IState.cpp           |   2 -
 workdir/assets/apple.png                      | Bin 0 -> 1211 bytes
 workdir/assets/pacman.png                     | Bin 0 -> 2732 bytes
 workdir/assets/pacmanDown.png                 | Bin 0 -> 2263 bytes
 workdir/assets/pacmanLeft.png                 | Bin 0 -> 2247 bytes
 workdir/assets/pacmanRight.png                | Bin 0 -> 2217 bytes
 workdir/assets/pacmanUp.png                   | Bin 0 -> 2237 bytes
 24 files changed, 214 insertions(+), 57 deletions(-)
 create mode 100644 source/application/Drawable/Entity/MyTexture.cpp
 create mode 100644 source/application/Drawable/Entity/MyTexture.h
 delete mode 100644 source/application/SelectCommand/ISelectCommand.cpp
 delete mode 100644 source/application/State/IState.cpp
 create mode 100644 workdir/assets/apple.png
 create mode 100644 workdir/assets/pacman.png
 create mode 100644 workdir/assets/pacmanDown.png
 create mode 100644 workdir/assets/pacmanLeft.png
 create mode 100644 workdir/assets/pacmanRight.png
 create mode 100644 workdir/assets/pacmanUp.png

diff --git a/CMakeLists.txt b/CMakeLists.txt
index cc0696b..6bb6638 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,8 @@ FetchContent_Declare(SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TA
 FetchContent_MakeAvailable(SFML)
 
 file(GLOB_RECURSE SOURCE_CPP source/*.cpp)
-add_executable(pacman ${SOURCE_CPP})
+file(GLOB_RECURSE SOURCE_H source/*.h)
+add_executable(pacman ${SOURCE_CPP} ${SOURCE_H})
 
 target_link_libraries(pacman PRIVATE sfml-window sfml-graphics sfml-system)
 target_compile_definitions(pacman PRIVATE ASSETS_PATH="${CMAKE_CURRENT_SOURCE_DIR}/workdir/assets/")
diff --git a/source/application/App/Application.cpp b/source/application/App/Application.cpp
index 6bac2e1..0c2126a 100644
--- a/source/application/App/Application.cpp
+++ b/source/application/App/Application.cpp
@@ -28,6 +28,5 @@ void Application::set_next_state(std::unique_ptr<IState>&& ptr_state) {
 
 void Application::apply_deffer_state_change() noexcept {
     if (m_ptr_state_next)
-        std::swap(m_ptr_state_current, m_ptr_state_next);
-    m_ptr_state_next.reset();
+        m_ptr_state_current = std::exchange(m_ptr_state_next, nullptr);
 }
\ No newline at end of file
diff --git a/source/application/App/Application.h b/source/application/App/Application.h
index d8c0124..a08c9a4 100644
--- a/source/application/App/Application.h
+++ b/source/application/App/Application.h
@@ -10,7 +10,7 @@ class Application : public IStateManager {
 public:
     Application();
     int run();
-    ~Application() = default;
+    ~Application() override = 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 653f125..5afea2d 100644
--- a/source/application/BobBuilder/GameBuilders.cpp
+++ b/source/application/BobBuilder/GameBuilders.cpp
@@ -1,9 +1,7 @@
 #include "GameBuilders.h"
 
-#include <random>
-
 CommonBuilder::CommonBuilder(float width, float height, float room_size) :
-            m_width(width), m_height(height), m_room_size(room_size){
+        m_width(width), m_height(height), m_room_size(room_size){
 }
 
 void CommonBuilder::create_context(float dynamic_objects_ratio) {
@@ -12,16 +10,28 @@ void CommonBuilder::create_context(float dynamic_objects_ratio) {
         for (auto& room : row)
             if (room != nullptr)
                 empty_rooms_buffer.emplace_back(room);
+
     float id = std::rand() % empty_rooms_buffer.size();
+    //в рандомное место располагаем пакмана
     m_context.pacman.set_location(empty_rooms_buffer[id]);
     auto it = std::next(empty_rooms_buffer.begin(), id);
     empty_rooms_buffer.erase(it);
-    //@todo располагать врагов
+
+    //располагаем врагов
+    size_t rooms_row = static_cast<size_t>(m_width / m_room_size);
+    size_t rooms_col = static_cast<size_t>(m_height / m_room_size);
+    for (size_t i = 0; i < rooms_row * rooms_col * dynamic_objects_ratio; i++) {
+        id = std::rand() % empty_rooms_buffer.size();
+        auto enemy = std::make_unique<Enemy>();
+        enemy->set_location(empty_rooms_buffer.at(id));
+        m_context.dynamic_objects.emplace_back(std::move(enemy));
+    }
 
     //располагаем еду
     for (auto it : empty_rooms_buffer) {
         auto food = std::make_unique<Food>();
         food->set_location(it);
+        food->set_texture(&FoodTexture::instance());
         m_context.static_objects.emplace_back(std::move(food));
     }
     empty_rooms_buffer.clear();
@@ -96,9 +106,84 @@ void SimpleBuilder::set_rooms_sides() {
 }
 
 void ComplexBuilder::create_rooms() {
+    size_t room_quantity_row = (m_height / m_room_size);
+    size_t room_quantity_col = (m_width / m_room_size);
 
+    int room_size = static_cast<int>(m_room_size);
+    auto starting_point = sf::Vector2f{(m_width - m_room_size*room_quantity_col)/2 + m_room_size/2, (m_height - m_room_size*room_quantity_row)/2 + + m_room_size/2};
+
+    for (int row = 0; row < room_quantity_row * room_size; row += room_size) {
+        std::vector<Room*> vector_row;
+        for (int col = 0; col < room_quantity_col * room_size; col += room_size) {
+            auto room = new Room(m_room_size);
+            room->set_position(sf::Vector2f {(col + starting_point.x), (row + starting_point.y)});
+            vector_row.emplace_back(std::move(room));
+        }
+        m_rooms.emplace_back(std::move(vector_row));
+    }
 }
 
 void ComplexBuilder::set_rooms_sides() {
+    size_t cols = m_rooms[0].size();
+    size_t rows = m_rooms.size();
+    for (int j = 0; j < cols; j++) {
+        m_rooms[0][j]->set_side(Room::Direction::UP, std::make_unique<Wall>(*m_rooms[0][j]));
+    }
+    for (int j = 0; j < cols; j++) {
+        m_rooms[rows - 1][j]->set_side(Room::Direction::DOWN, std::make_unique<Wall>(*m_rooms[rows - 1][j]));
+        if (j != cols - 1) {
+            m_rooms[rows  - 1][j]->set_side(Room::Direction::RIGHT, std::make_unique<Pass>(*m_rooms[rows - 1][j], *m_rooms[rows - 1][j+1]));
+            m_rooms[rows - 1][j+1]->set_side(Room::Direction::LEFT, std::make_unique<Pass>(*m_rooms[rows - 1][j+1], *m_rooms[rows - 1][j]));
+        }
+    }
+    for (int i = 0; i < rows ; i++) {
+        m_rooms[i][0]->set_side(Room::Direction::LEFT, std::make_unique<Wall>(*m_rooms[i][0]));
+    }
+    for (int i = 0; i < rows; i++) {
+        m_rooms[i][cols - 1]->set_side(Room::Direction::RIGHT, std::make_unique<Wall>(*m_rooms[i][cols - 1]));
+    }
 
-}
\ No newline at end of file
+    std::vector<int> row(cols);
+    int count = 0;
+    for (; count < cols; row[count] = count, count++);
+    for (int i = 0; i < rows - 1; i++) {
+        for (int j = 0; j < cols - 1; j++) {
+            if (rand() % 2) {
+                m_rooms[i][j]->set_side(Room::Direction::RIGHT, std::make_unique<Wall>(*m_rooms[i][j]));
+                m_rooms[i][j+1]->set_side(Room::Direction::LEFT, std::make_unique<Wall>(*m_rooms[i][j+1]));
+            }
+            else {
+                m_rooms[i][j]->set_side(Room::Direction::RIGHT, std::make_unique<Pass>(*m_rooms[i][j], *m_rooms[i][j+1]));
+                m_rooms[i][j+1]->set_side(Room::Direction::LEFT, std::make_unique<Pass>(*m_rooms[i][j+1], *m_rooms[i][j]));
+                int temp = row[j + 1];
+                for (int k = 0; k < cols; k++) {
+                    if (row[k] == temp) row[k] = row[j];
+                }
+            }
+        }
+        for (int j = 0; j < cols; j++) {
+            if (rand() % 2) {
+                int temp = 0;
+                for (int k = 0; k < cols; k++) {
+                    if (row[k] == row[j] && !m_rooms[i][k]->get_side(Room::Direction::DOWN)) temp++;
+                }
+                if (temp > 1) {
+                    m_rooms[i][j]->set_side(Room::Direction::DOWN, std::make_unique<Wall>(*m_rooms[i][j]));
+                    m_rooms[i+1][j]->set_side(Room::Direction::UP, std::make_unique<Wall>(*m_rooms[i+1][j]));
+                }
+                else {
+                    m_rooms[i][j]->set_side(Room::Direction::DOWN, std::make_unique<Pass>(*m_rooms[i][j], *m_rooms[i+1][j]));
+                    m_rooms[i+1][j]->set_side(Room::Direction::UP, std::make_unique<Pass>(*m_rooms[i+1][j], *m_rooms[i][j]));
+                }
+            }
+            else {
+                m_rooms[i][j]->set_side(Room::Direction::DOWN, std::make_unique<Pass>(*m_rooms[i][j], *m_rooms[i+1][j]));
+                m_rooms[i+1][j]->set_side(Room::Direction::UP, std::make_unique<Pass>(*m_rooms[i+1][j], *m_rooms[i][j]));
+            }
+        }
+        for (int j = 0; j < cols; j++) {
+            if (m_rooms[i][j]->get_side(Room::Direction::DOWN)) row[j] = count++;
+        }
+    }
+
+}
diff --git a/source/application/Context/Context.cpp b/source/application/Context/Context.cpp
index fe23398..fe3ae59 100644
--- a/source/application/Context/Context.cpp
+++ b/source/application/Context/Context.cpp
@@ -14,13 +14,13 @@ 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();
 }
 
 void ContextManager::reset(GameContext &&context) {
diff --git a/source/application/Context/Context.h b/source/application/Context/Context.h
index 456d2e3..785b985 100644
--- a/source/application/Context/Context.h
+++ b/source/application/Context/Context.h
@@ -4,13 +4,14 @@
 #include <istream>
 #include <list>
 
-class GameContext {
-public:
+struct GameContext {
     enum State { INGAME, WIN, LOST } state = INGAME;
     std::list<std::unique_ptr<IDynamicEntity>> dynamic_objects;
     std::list<std::unique_ptr<IStaticEntity>> static_objects;
+    std::vector<MyTexture*> m_textures;
+    MyTexture* m_pacman_texture;
+    MyTexture* m_food_texture;
     Pacman pacman;
-public:
     GameContext clone();
 };
 
diff --git a/source/application/Drawable/DrawMenu/Font/Font.h b/source/application/Drawable/DrawMenu/Font/Font.h
index 240f722..689eb11 100644
--- a/source/application/Drawable/DrawMenu/Font/Font.h
+++ b/source/application/Drawable/DrawMenu/Font/Font.h
@@ -7,7 +7,7 @@ public:
     MyFont(const MyFont&) = delete;
     MyFont& operator=(const MyFont&) = delete;
     static MyFont& Instance();
-    operator const sf::Font&() const; //@todo why is this necessary
+    operator const sf::Font&() const; //приведение типа
 
 private:
     MyFont();
diff --git a/source/application/Drawable/DrawMenu/Menu/Menu.cpp b/source/application/Drawable/DrawMenu/Menu/Menu.cpp
index 833f2c6..6ffe566 100644
--- a/source/application/Drawable/DrawMenu/Menu/Menu.cpp
+++ b/source/application/Drawable/DrawMenu/Menu/Menu.cpp
@@ -21,7 +21,7 @@ Menu::Menu(IStateManager& state_manager) {
             config::MEDIUM_GAME_TITLE,
             config::MEDIUM_GAME_ENEMY_RATIO);
     auto hard_director = std::make_unique<GameBuilderDirector>(
-            std::make_unique<SimpleBuilder>(
+            std::make_unique<ComplexBuilder>(
                     config::GAME_VIDEO_MODE.width, config::GAME_VIDEO_MODE.height,
                     config::ROOM_SIZE),
             config::GAME_VIDEO_MODE,
diff --git a/source/application/Drawable/Entity/IEntity.cpp b/source/application/Drawable/Entity/IEntity.cpp
index ab32bca..8bb10e2 100644
--- a/source/application/Drawable/Entity/IEntity.cpp
+++ b/source/application/Drawable/Entity/IEntity.cpp
@@ -7,9 +7,10 @@ void IEntity::set_location(Room* ptr_room) {
 }
 
 Food::Food() {
-    m_shape = sf::CircleShape(config::GAME_FOOD_SIZE);
+    m_shape = sf::CircleShape(config::GAME_FOOD_SIZE/2);
+    m_shape.setOrigin({ config::GAME_FOOD_SIZE/2, config::GAME_FOOD_SIZE/2 });
+    set_texture(&FoodTexture::instance());
     m_shape.setFillColor(config::GAME_FOOD_COLOR);
-    m_shape.setOrigin({config::GAME_FOOD_SIZE/2, config::GAME_FOOD_SIZE/2});
 }
 
 std::unique_ptr<IStaticEntity> Food::clone() const {
@@ -17,7 +18,8 @@ std::unique_ptr<IStaticEntity> Food::clone() const {
 }
 
 void Food::prepare_for_drawing() {
-    m_shape.setPosition(m_ptr_room->get_position());
+    m_sprite.setTexture(m_ptr_texture->get_texture());
+    m_sprite.setPosition(m_ptr_room->get_position()+sf::Vector2f(-10, -10));
 }
 
 std::unique_ptr<IGameEvent> Enemy::accept(IVisitor* ptr_visitor) {
@@ -28,15 +30,13 @@ 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);
+    prepare_for_drawing();
+    window.draw(m_sprite);
 }
 
 Enemy::Enemy() {
-    m_shape = sf::CircleShape(config::GAME_ENEMY_SIZE);
+    m_shape = sf::CircleShape(config::GAME_ENEMY_SIZE/2);
     m_shape.setFillColor(config::GAME_ENEMY_COLOR);
     m_shape.setOrigin({config::GAME_ENEMY_SIZE / 2, config::GAME_ENEMY_SIZE / 2});
 }
@@ -49,7 +49,7 @@ void Enemy::prepare_for_drawing() {
     m_shape.setPosition(m_ptr_room->get_position());
 }
 
-void Enemy::draw_into(sf::RenderWindow &window) {
+void Enemy::draw_into(sf::RenderWindow& window) {
     prepare_for_drawing();
     window.draw(m_shape);
 }
diff --git a/source/application/Drawable/Entity/IEntity.h b/source/application/Drawable/Entity/IEntity.h
index 6a83d09..f0348c7 100644
--- a/source/application/Drawable/Entity/IEntity.h
+++ b/source/application/Drawable/Entity/IEntity.h
@@ -2,6 +2,7 @@
 
 #include "../IDrawable.h"
 #include "../../Event/IGameEvent.h"
+#include "MyTexture.h"
 
 class Room;
 class Food;
@@ -30,6 +31,9 @@ public:
 class IStaticEntity : public IEntity, public IVisitable {
 public:
     virtual std::unique_ptr<IStaticEntity> clone() const = 0;
+    virtual void set_texture(MyTexture* ptr_texture) {m_ptr_texture = ptr_texture; }
+protected:
+    MyTexture* m_ptr_texture;
 };
 
 class IDynamicEntity: public IEntity, public IVisitable {
@@ -52,14 +56,17 @@ private:
     sf::Clock m_clock;
 };
 
-class Food: public IStaticEntity {
+class Food: public IStaticEntity{
 public:
     Food();
     void draw_into(sf::RenderWindow& window) override;
     void prepare_for_drawing() override;
+    void set_texture(MyTexture* ptr_texture) override { m_ptr_texture = ptr_texture; }
     std::unique_ptr<IStaticEntity>  clone() const override;
     std::unique_ptr<IGameEvent> accept(IVisitor* ptr_visitor) override;
     ~Food() override {};
 private:
     sf::CircleShape m_shape;
+    MyTexture* m_ptr_texture;
+    sf::Sprite m_sprite;
 };
\ No newline at end of file
diff --git a/source/application/Drawable/Entity/MyTexture.cpp b/source/application/Drawable/Entity/MyTexture.cpp
new file mode 100644
index 0000000..a7d4278
--- /dev/null
+++ b/source/application/Drawable/Entity/MyTexture.cpp
@@ -0,0 +1,28 @@
+#include "MyTexture.h"
+
+PacmanTexture::PacmanTexture() {
+    m_texture_up.loadFromFile(std::string(ASSETS_PATH) + "pacmanUp.png");
+    m_texture_down.loadFromFile(std::string(ASSETS_PATH) + "pacmanDown.png");
+    m_texture_right.loadFromFile(std::string(ASSETS_PATH) + "pacmanRight.png");
+    m_texture_left.loadFromFile(std::string(ASSETS_PATH) + "pacmanLeft.png");
+}
+
+//в зависимости от направления - разные текстуры
+sf::Texture& PacmanTexture::get_texture() {
+    switch (m_direction) {
+        case Direction::UP:
+            return m_texture_left;
+        case Direction::DOWN:
+            return m_texture_right;
+        case Direction::RIGHT:
+            return m_texture_up;
+        case Direction::LEFT:
+            return m_texture_down;
+    }
+}
+
+FoodTexture::FoodTexture() {
+    if (!m_texture_food.loadFromFile(std::string(ASSETS_PATH) + "apple.png"))
+        throw std::runtime_error("Can't added Texture for food");
+}
+
diff --git a/source/application/Drawable/Entity/MyTexture.h b/source/application/Drawable/Entity/MyTexture.h
new file mode 100644
index 0000000..4af54f3
--- /dev/null
+++ b/source/application/Drawable/Entity/MyTexture.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "SFML/Graphics.hpp"
+
+class MyTexture {
+public:
+    MyTexture() = default;
+    enum Direction { UP, DOWN, RIGHT, LEFT };
+    virtual sf::Texture& get_texture() = 0;
+    MyTexture(const MyTexture&) = delete;
+    MyTexture& operator=(const MyTexture&) = delete;
+    void set_direction(Direction direction) { m_direction = direction; }
+protected:
+    Direction m_direction = UP;
+};
+
+//texture for Pacman
+class PacmanTexture : public MyTexture {
+public:
+    static PacmanTexture& instance() { static PacmanTexture instance; return instance; }
+    sf::Texture& get_texture() override;
+private:
+    PacmanTexture();
+    sf::Texture m_texture_up, m_texture_down, m_texture_right, m_texture_left;
+};
+
+//texture for Food
+class FoodTexture : public MyTexture {
+public:
+    static FoodTexture& instance() { static FoodTexture instance; return instance; }
+    sf::Texture& get_texture() override { return m_texture_food; }
+private:
+    FoodTexture();
+    sf::Texture m_texture_food;
+};
diff --git a/source/application/Drawable/Entity/Pacman.cpp b/source/application/Drawable/Entity/Pacman.cpp
index e20ab2d..b47166f 100644
--- a/source/application/Drawable/Entity/Pacman.cpp
+++ b/source/application/Drawable/Entity/Pacman.cpp
@@ -2,30 +2,33 @@
 #include "../../../../workdir/config.h"
 
 Pacman::Pacman() {
-    m_shape = sf::CircleShape(config::GAME_PACMAN_SIZE/2);
+    m_shape = sf::CircleShape(config::GAME_PACMAN_SIZE);
     m_shape.setFillColor(config::GAME_COLOR_PACMAN);
-    m_shape.setOrigin({config::GAME_PACMAN_SIZE/2, config::GAME_PACMAN_SIZE/2});
+    set_texture(&PacmanTexture::instance());
+    m_shape.setOrigin({config::GAME_PACMAN_SIZE, config::GAME_PACMAN_SIZE});
 }
 
 void Pacman::move(Room::Direction direction) {
     m_ptr_room->get_side(direction)->enter(this);
+    m_ptr_texture->set_direction(static_cast<MyTexture::Direction>(direction));
 }
 
 void Pacman::prepare_for_drawing() {
-    m_shape.setPosition(m_ptr_room->get_position());
+    m_sprite.setTexture(m_ptr_texture->get_texture());
+    m_sprite.setPosition(m_ptr_room->get_position()+sf::Vector2f(-20, -20));
 }
 
-std::unique_ptr<IGameEvent> Pacman::visit(Food *ptr_food) {
+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) {
+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) {
+void Pacman::draw_into(sf::RenderWindow& window) {
     prepare_for_drawing();
-    window.draw(m_shape);
-}
+    window.draw(m_sprite);
+}
\ No newline at end of file
diff --git a/source/application/Drawable/Entity/Pacman.h b/source/application/Drawable/Entity/Pacman.h
index 8e5f5f6..3f38479 100644
--- a/source/application/Drawable/Entity/Pacman.h
+++ b/source/application/Drawable/Entity/Pacman.h
@@ -2,16 +2,20 @@
 
 #include "IEntity.h"
 #include "../Maze/Maze.h"
+#include "MyTexture.h"
 
 class Pacman : public IEntity, public IVisitor {
 public:
     Pacman();
     void move(Room::Direction direction);
     void prepare_for_drawing() override;
+    void set_texture(MyTexture* ptr_texture) { m_ptr_texture = ptr_texture; }
     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
+    sf::Sprite m_sprite;
+    MyTexture* m_ptr_texture;
+};
diff --git a/source/application/Drawable/Maze/Maze.h b/source/application/Drawable/Maze/Maze.h
index 967923d..1b7219a 100644
--- a/source/application/Drawable/Maze/Maze.h
+++ b/source/application/Drawable/Maze/Maze.h
@@ -13,7 +13,6 @@ public:
 class Room: public IDrawable {
 public:
     enum Direction { INVALID = -1, LEFT, RIGHT, UP, DOWN };
-
     explicit Room(float size);
     float get_size() { return m_rectangle.getSize().x; }
     void set_position(sf::Vector2f pos) { m_rectangle.setPosition(pos); }
@@ -31,7 +30,7 @@ public:
 class Maze: public IDrawable {
 public:
     Maze() = default;
-    Maze(std::vector<Room*>& rooms) : m_rooms(rooms) {};
+    explicit Maze(std::vector<Room*>& rooms) : m_rooms(rooms) {};
     void draw_into(sf::RenderWindow& m_window) override;
 private:
     std::vector<Room*> m_rooms;
diff --git a/source/application/SelectCommand/ISelectCommand.cpp b/source/application/SelectCommand/ISelectCommand.cpp
deleted file mode 100644
index 4669ecd..0000000
--- a/source/application/SelectCommand/ISelectCommand.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "ISelectCommand.h"
-
diff --git a/source/application/State/GameState.cpp b/source/application/State/GameState.cpp
index bab1573..db705ac 100644
--- a/source/application/State/GameState.cpp
+++ b/source/application/State/GameState.cpp
@@ -23,15 +23,19 @@ void GameState::event_handling() {
 void GameState::process_key_pressed(sf::Keyboard::Key code) {
     switch (code) {
         case sf::Keyboard::W:
-            m_context_manager.get_current_context().pacman.move(Room::UP);
+            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;
     }
@@ -41,25 +45,21 @@ 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_ptr : context.dynamic_objects) {
-        entity_ptr->action();
+    for (auto& ptr_entity : context.dynamic_objects) {
+        ptr_entity->action();
         IVisitor* ptr_visitor = &(context.pacman);
-        game_events.emplace_back(entity_ptr->accept(ptr_visitor));
+        auto ptr_event = ptr_entity->accept(ptr_visitor);
+        if (ptr_event)  game_events.emplace_back(std::move(ptr_event));
     }
     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));
+        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()) {
-            game_events.emplace_back(std::move(std::make_unique<LostGame>()));
-        }
-    }
-    for (int i = 0; i < game_events.size(); i++) {
+
+    for (int i = 0; i < game_events.size(); i++)
         game_events[i]->handle(&m_context_manager.get_current_context());
-    }
+
     if (context.static_objects.empty()) {
         game_events.emplace_back(std::move(std::make_unique<WinGame>()));
     }
@@ -80,10 +80,8 @@ void GameState::render() {
     }
     m_maze.draw_into(m_window);
     context.pacman.draw_into(m_window);
-    for (auto& obj :  context.static_objects) {
+    for (auto& obj :  context.static_objects)
         obj->draw_into(m_window);
-    }
-
 
     for (auto& el : context.dynamic_objects)
         el->draw_into(m_window);
@@ -92,7 +90,8 @@ void GameState::render() {
 
 bool GameState::do_step() {
     event_handling();
-    update();
+    if (m_context_manager.get_current_context().state == GameContext::INGAME)
+        update();
     render();
     return true;
 }
diff --git a/source/application/State/IState.cpp b/source/application/State/IState.cpp
deleted file mode 100644
index 528669c..0000000
--- a/source/application/State/IState.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "IState.h"
-
diff --git a/workdir/assets/apple.png b/workdir/assets/apple.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc27ccc400f05db3ddff79abddf562bfd8949f70
GIT binary patch
literal 1211
zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa3dtTpz6=aiY77hwEes65fI<x~
z7#K<o7#Ln9FfdrnU|<k0n6oR;hJk_cVt`MGD^P)mfskH~mcukFr2zS$177mpvS(zJ
z9e8;>xOmd}1fzNQk4h^Zl2$w=qjW-A=`@g(QQ9FXzfDrUSU@<NPbi63Ae5Ugh?~!y
zljpy=%m4rX^Z14TI|k<R3z;_<S#_A2HyT;A8k^Pv-N4|r&e?aX8w7c+cX66y<Fm=t
zbB(jx3P-Pvu6{c`e73lO)a-DtY_z&1s&q+K<*>BkItG!nR?Dc>E}<LU0=BzHtaDuv
zVRT<c^^Tk>(5YJ`<*&%7Tv1g!W~O;pPW85&>Sb9Kpo6c-s@#-Pyb0zWlu|q{tpt<;
zqGQsEC!`gRNrSut^aW7-x}3^2Srs5-i=-ToaaC3Ys26AyklZCD53~Zv1_}aQ0yGxL
z0CLaBC;_E_+zYbGmt>WJ!2%2)AR8!>$|qRJFI>bgoWm~!L_kkPt#LhWrZut9B6_vU
z4tM>l8XEWHRPR~XJ*cXGU~GNBR(nCB$#pgL`?9Kc<<;&1k+J2yw5)qux8HN|x+krC
zZ^GnzD_7q$G{2{)ac}m#dz-f0Q_%vt;a*YMy{6WCN}Bf+)bA;(149EC_?vi+10$ND
ztR%=U7)av-%xui8OpFz~x9-T2ToO=n?(gp6_e-K8CHdli{R4sTVO$+g|NVW^B3gCj
zV!5#9i>E4@Dw^W0H?B2_E}6gN-+YIuzYnIRANe)O&V1*=f|4C3Oq`soY-JwnO@Y=j
zCV9KNNHZl|Spwv67I;J!Gca%qfiUBxyLEqng6t)pzOL*qnb|n_dE_&X>;mdx@pN$v
zk+__kaDY!j@`<R3h{((-Q)UV_>1eIWdL=b0>Xy|S4o5T5Slhow%+AWm!okL6D-_t9
zcebYPoVvAl?cBZ1%FOB!6TFX}yt#DIrd7L^UAuaAZlkoyvBwWzhKAq2aO29IOSi5)
zd;9n_x5$&vpYz|pc=IZ6C2QB#t*k7cm|0ny{!~}}{*`@OK|vuxK*=KU(UOz7E1DGl
z1uyekeN<qM-C|x}fsDXh-58#%i2)fA7BMSym5jV3o&*R^&1gyBY1X*mo}{&L^5a{N
z($296O@1tS<Y1E!4`-)m?n%v+nYk||XYx$Cppba})VY&WC!ITeQeU8feV$KZU}2|@
zb7o=SLK$W~1_n09q)L&af7yXSq*~${QIe8al4_M)lnSI6j0}uSbq$Pl4a`CeEUXMo
ztqhH{4GgRd3?@3SP(;y?o1c=IR*74~137`YKn)sj8%i>BQ;SOya|>|m+0Jd~1k@t~
x(i5DYR#Ki=l*-_klAn~S;FejGTAp8&U98|7Z1!T$rXHX=22WQ%mvv4FO#mDftU>?)

literal 0
HcmV?d00001

diff --git a/workdir/assets/pacman.png b/workdir/assets/pacman.png
new file mode 100644
index 0000000000000000000000000000000000000000..9dfa35d9d504f7e413ad1e5180b9821dfab11f3b
GIT binary patch
literal 2732
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

literal 0
HcmV?d00001

diff --git a/workdir/assets/pacmanDown.png b/workdir/assets/pacmanDown.png
new file mode 100644
index 0000000000000000000000000000000000000000..18d63290bb82e97f70b629c745b29e4f8f443d5b
GIT binary patch
literal 2263
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
Isl}WB1pZ?yv;Y7A

literal 0
HcmV?d00001

diff --git a/workdir/assets/pacmanLeft.png b/workdir/assets/pacmanLeft.png
new file mode 100644
index 0000000000000000000000000000000000000000..cfad9cd3a0718cf3fe8a89621fe84d0254911c10
GIT binary patch
literal 2247
zcmcImc~BEq91g7qf+$*Q)rzjGVytX-H@gYR4ygiBK?$NpiAUAFLQ<0Kk}M|RSRI7X
zSgfN{JkU`=biAr9T95HS#bZ2L$D`gNRy=F9D2_)x`W8a!bkyOW?#$bLZ{PR6-}gKA
zH|tMN8xj%LHB6yUM5H7eM}ntP9-*zkz3BB0CwR0GlgD}#ittb55uzwr)>)xwdCG3K
zNETBn#R^Up%?S*z@;OC-Rw&{J_(Yn`;w6aTGwm(|{BTz#4B0sYoS`vcCNYV(*^~3!
z{HVM%Gn<#i>N$A8mr%Tq0t8N8q9LEt;qp*E1Khw%fw}w|g`ozBlx2VuWP^~!lnx~c
zZXVL8v<Qon8YoV$!nFjc*T+I?4A-HU4#f!s*HR=#snt;6f`K(RXQf6O2M26{l>xR%
zl1QPb*Xvbz36<c^L~*@dk78<6twsO>@#MNB+K0G2y_y(|yoYt$MaeF>AeoV7gdE8L
z1Eq~FIK?2X%M%C_2pH<4MHE+IvP(@slj*}yr!$E5NQ0&TD*?UlB=(qdMIIf=dxRV}
z%MY5uyQE%C#yB>3R?Klb8a(A#ly~q>0P_H0c+iw+6C}Z76W-%Ta69OYNF}*>S`yr5
zL2xuBD!qvXN=lLwqlc6kb{8jjJ^f@+fit|3mUsiK#?&N&X%GT8<0PdfC<5<~5fp|s
zLQS9)I9j5c2NpQHHMcoXlZi@kc_iA!@+n3G3`D8yc8=mTq?ToH4Z`7Z45H;o5}`2+
zLvRLTXikkY8jNhv1<o4<Hb;)2e7>=AIe`Tn!5~otiIW&X>JXCEl8BBa^$1N8aR|<1
zG|8w*jOH7?1Z>0IcJT4gj<;E5RUBYsaE`&~I4z>p6B<OPCbfu8uOSgDj^i3!%V-Fz
z8iqKQvI=e|4NArCq%(O`bY;TOziN^Mhu}5|9Edp~7c^i8c9ZQMkiFc%Co+o94$K^O
zsG;sCnw87l0JCzQc@7S|w!b5K&C}UP>$UNK^aIIngn0z3<fYwwLMDiGbLtCypMDQL
z<-_Wmm;3)$eIU53jdo@7po5~Y><=pUn#R<i|IJ#%-dlaC2@aZ_JPmePun6{P-UX=L
zpbKwrwW>s+_-I**F~Mvp{Ow}pytZ`beRU`ABeSaf-$Hu7F<qA*T5QZO_|BHR^^4U9
zrmtL?Q2PCywaS#Jj?+WRPDi#`FznZf1y$7#l-2W>F1;E}WO)|~6~F9$NIX9AIR5cV
zU)-F}=U_9ZUhrFc`uo7Kzw1>@X_2_6X78sLX6LLnk1s2Xcoljs>_Jw4VJDeg`Dn!9
zLyN>#SuM9mR)5oR>Q67wsFy{Hj=n0ZeX)4uv*`HyF^hBRx_3L`TQR2|?wD9>nfK(#
zo)%kFudPSjqfZT8ez{ob^7U@<2A;x>!={Zs=$q-y-@m-(@WVq?T9@6!jz`iNk7i!1
zXCfwTIH#PoEp>TpiFNSd>7_NbYm1XR9OvdMT|3qjA=9fmEPGI)O=WiP`*`Dl#BB@8
zcg`4p!CYuH*lr%G>6&U@ozni+<JcX;#kz;RtLMhFt0}mC@X>^cyPl|@zw&R<*^+x)
zhEAWzE1lFWELWvE);5h9`ZRrZ;ibLNw~MDP*_oiU6yV(skGg)N|FH?h#pRpZt-F)D
z;E45pWbBy-72W%uytui2pVp-{DHE!;g<RP%Ghv5sf8?&e;=^4XZq;O8{i^k~mgkGx
zyc}8E&lk4+$$;?o1@WJ~IXG{9)ZP8Y=pi{VCv$s-%wxtppPiBKtu$s=Wh51qF4&r#
zp&K|*tXq3^F+X<G#y0-?6*nt8myDS^&L5@Om^x`~c+#<Qad5?GUG2I{6)Uj51(z?^
zCq~7cExa)+X48#|uPg6qH`T0}{G$cybhJ>4{$X8p-rd_dXX_p7{+@AuVf&%Z{bgs=
zbtCdEi+{d0e&YE*5)YO98Dq>mKIzQGEt>4mr-ger_vlpD_I5$l`i+am<&nL|hHsnd
za6I2dR4GTSUvgzbapg3BSwz;TXUEpmzlk%hD)08J<<*d)A(k%pmdd{xDTC6Cn-VAI
F{{z&(I+_3g

literal 0
HcmV?d00001

diff --git a/workdir/assets/pacmanRight.png b/workdir/assets/pacmanRight.png
new file mode 100644
index 0000000000000000000000000000000000000000..9613050a23c47f95d5e51ed3bcf44514e85e68ad
GIT binary patch
literal 2217
zcmcImc~I0=9A2rkirNB#V3jcwEQ*rNZZ_-@SsB~~L0uG~fZ&x)-Yyw-lXVl8l~P-;
z7LV$vt<xe_v9;EUI!GNYRVpf2FVJf79O=-hC-s<WWt@tAfo1D-tiwNjGfCci`QG>Y
zen)<jWz*6p4hniRNTE;+N=r3QhtJXS)$dh!U)j0e2_OAksWU`{V!&Ye>Z2&Hh*T&7
z&vIG0Qm$nR#RyI%%?eha^g3M-txzN+dR;VA2qeS`>>O`I?|uIRig2tE&55_DEG`o$
z;8IK6AhRSrizz8&3@n;B9!c<0kiZEf8u2<EyhwSCXcsR9=khj=B3%%v(1<3<29aFL
zG{hvh0TQp&VvL%MM|1|ITB{)qhB$;!sr9%@kE=D9T1$~CiXaf*K%q4^Yon%{Q+&4I
z%7_+7l8eIe;^Jauu|_Gl?YP=tFyJZzCkPB8FmXOF(O!%fqk9<4KxEvUOX36`kr`>L
zP$U^qsI=P!r^`>vi@q?yfZ<-+g{ze+*`*$!#qx5f)9FWxQnCkH@#%dbv6waA1@P%W
z6pGvoNcI3;itaJSGXAr!BDbT<Q<lMj12`c}gu>K*Q?3F*62t=GKm72&_Iu-^Om09+
zf;&qP96gDe*299BOmboj$mkr7XN6)hRu<(u1I)Apj3}WZNK6%vY1CP2k|Ib-LylEx
zD3z)kYJsJ|(h}V}u)uP*`MrT!EL0jVN;J=aG_w(fqLduRQU;)7RW>WY3_2)@(2)dY
z)mn9!Mx}|@X;__(U_qBIc-|~9MREk?^WBxp3Jm1%2Z>@yJ#Ezj0wYP%im^75#PkN6
z7Gnt&96Ca;156LwR5u4d9@_CdtE`HJjD$g_i6>bdW&kQZq#)r<r=>B1wb?XQn}LA)
zD8e$7O>jGDSSp;8wgcS7+fn2nH73C!xGe$;W3G`48nQz#QaKT3Z@%vn$prI!GY5xs
z)g47Ma=9B(M$R)}QQtQAg6Q>5XE$we0f3}0Nq#p>6l_v4?FLD980p^B7ye)RMcVUn
z^}Wme|Et~?T&95L?ErRA9F_gS<zCaB8vNf`>w5QGU+RIwW+zYmT^26<eH!qP+6}w#
z<NQGf6^eibY38J?+@+^484JTQ!Wtj6^0vW)!;3P4lfvp7FHD^anAop#%ldg1ypqvg
zg`J<2A2RH$a%oFmY~7I1uodt3iy7JIm|e`w8^u<%H{ETjUH2DVKF;2hP*L;vs%V=$
zHnSE)u66~5WY?C~EmF^{-{xt|*mv9N*|L0LMRQJIrSo`bE{|>w8OPro?@qhjzm=<e
zbTM%>__8B(7ZZGP*(2glrtj8@fC%-fy!O?>RYMaRqn0&fx7Sx!1YA~^nJg_gs`2lp
zr4Jq0kt3O^$<TXM$fRu@+NPlGJFLRI%fUx2Z65|#-IA8S(N<8uW$nk+<LWlAPk*qb
z?Ob_7Y2GhiF*O6?wg$H7%qfK*pb5u3m60QIO0(>)5mT$9i-g$2LkEV(jXA#P40(X_
z)U3QT;kPP#s(wcK+I<^tE!pHP%W!aX<`7ihaw07;u;u>iyG!Q%)I2Dp|7mA)dM)U)
zZ^_NL!fWnNmiAk4dS_hB>O<7*V>zvNY}djfvd_Ti#4Ks~CUgD$zO8|kr>76618_+d
z3D%5i2%mZP5I^(g?<JuZn`a$Z(t41(Wsj-~T6`g7=fqP#CvjmT@`gTK5v7lqGvoaI
z$paRGJLAf>d=_rjzIE7A+1C6kntmej-gSCdQ~rj%>rQRmR{PriG0#SQ^vq&BxFWhC
zWp~uM4e!QWdT2UFEj(gr(XQQji|WYkC^&zp&+zPaVUKe7nmI?46Yl(RCH`t=`>M|y
zW?jvl_2Z-)Wo;)dBi|lSv#M6`##Vf><7w-1<Vj!8@lBnE(xcz*Ma&(Go70X|h3&IO
zHoNjVYf1-3+^^e6UyI5=d*%9e>B-##A)khppFQxNX-d#jYkp_I9{Qc4l>93j<)4YP
M<aG0{33C_y4Uiff=Kufz

literal 0
HcmV?d00001

diff --git a/workdir/assets/pacmanUp.png b/workdir/assets/pacmanUp.png
new file mode 100644
index 0000000000000000000000000000000000000000..62ba3dcdcaed1efe5e18561316b57dd2f7b39b95
GIT binary patch
literal 2237
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
Awg3PC

literal 0
HcmV?d00001

-- 
GitLab