diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4179b1e28d7998f5312d37d1ec05bf37035c8e90..b958d238cafda94456216ad755b47f5629e4b155 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,12 +8,7 @@ FetchContent_Declare(SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TA
 FetchContent_MakeAvailable(SFML)
 
 
-add_executable(pacman source/main.cpp
-					source/${SOURCE_CPP}
-					source/State/${SOURCE_CPP}
-					source/Menu/${SOURCE_CPP}
-					source/Draw/${SOURCE_CPP}
-					source/Command/${SOURCE_CPP})
+add_executable(pacman source/main.cpp source/Application.cpp source/State/SelectState.cpp source/State/IWindowKeeper.cpp source/State/IState.cpp source/Menu/Menu.cpp source/Menu/Button.cpp "source/Draw/MyFont.cpp")
 
 target_link_libraries(pacman PRIVATE sfml-window sfml-graphics sfml-system)
-
+target_compile_definitions(pacman PRIVATE FONT_PATH="${CMAKE_CURRENT_SOURCE_DIR}/source/Assets/Fonts/Adbxtra.ttf")
diff --git a/source/Application.cpp b/source/Application.cpp
index 2365afe7bff9f4044c49cf6ac7dacc6183746ed8..be99b9b607f1402b754ffb4524c1b53728e6987c 100644
--- a/source/Application.cpp
+++ b/source/Application.cpp
@@ -1,14 +1,14 @@
 #include "Application.h"
+#include "State/SelectState.h"
+#include "Config/Config.h"
+#include <iostream>
 
-
-
-Application::Application():m_ptr_state_current(std::make_unique<SelectState>(*this, "Menu")) {}
-
+Application::Application() : m_ptr_state_current(std::make_unique<SelectState>(*this, config::SELECT_LEVEL_VIDEO_MODE, config::SELECT_LEVEL_TITLE)) {}
 
 int Application::run() {
 	try {
 		while (m_ptr_state_current->do_step())
-			apply_deffer_state_change();
+			apply_deferred_state_change();
 	}
 	catch (std::exception& ex) {
 		std::cout << ex.what() << '\n';
@@ -22,10 +22,10 @@ int Application::run() {
 }
 
 void Application::set_next_state(std::unique_ptr<IState> state) {
-	m_ptr_state_next = std::move(state)
+	m_ptr_state_next = std::move(state);
 }
 
-void Application::apply_deffer_state_change() {
+void Application::apply_deferred_state_change() {
 	if (m_ptr_state_next)
 		std::swap(m_ptr_state_current, m_ptr_state_next);
 	m_ptr_state_next.reset();
diff --git a/source/Application.h b/source/Application.h
index ef577f8d992f17b42edf09c15cf156a1b1ff6889..de2ec5d354ac24e86eb7810f4b821cb89602b9f2 100644
--- a/source/Application.h
+++ b/source/Application.h
@@ -1,15 +1,6 @@
 #pragma once
-
-#include "State/IState.h"
-#include <iostream>
-
-
-class IStateManager {
-public:
-	virtual void set_next_state(std::unique_ptr<IState> state);
-	virtual ~IStateManager();
-};
-
+#include "./State/IState.h"
+#include <memory>
 
 class Application : public IStateManager {
 private:
diff --git a/source/Assets/Fonts/Adbxtra.ttf b/source/Assets/Fonts/Adbxtra.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..d01707ee11f98057b86b5737e29a9490febf057b
Binary files /dev/null and b/source/Assets/Fonts/Adbxtra.ttf differ
diff --git a/source/Assets/Fonts/Calibri-Light.ttf b/source/Assets/Fonts/Calibri-Light.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..9533e115df6a5005c1002929fb89f36c9991b476
Binary files /dev/null and b/source/Assets/Fonts/Calibri-Light.ttf differ
diff --git a/source/Builder/CommonBuilder.h b/source/Builder/CommonBuilder.h
index 075657205beaa0dbe16e4a6149ad2610d270667c..bf63dfe3e418e7bf1c7c3a6bab581cf37d56dcdf 100644
--- a/source/Builder/CommonBuilder.h
+++ b/source/Builder/CommonBuilder.h
@@ -10,6 +10,7 @@ private:
 	GameContext m_context;
 	std::unique_ptr<GameState> m_game_state;
 public:
+	CommonBuilder(float width, float height, float room_size) : m_height(height), m_width(width), m_room_size(room_size) {}
 	void create_context(float dynamic_obj_ratio);
 	void create_state(IStateManager& state_manager, sf::VideoMode mode, std::string window_title);
 	void set_all_to_state();
diff --git a/source/Builder/GameBuilderDirector.h b/source/Builder/GameBuilderDirector.h
new file mode 100644
index 0000000000000000000000000000000000000000..97646e7e45f9eea76d512da457ab7ffd02f6b4e0
--- /dev/null
+++ b/source/Builder/GameBuilderDirector.h
@@ -0,0 +1,15 @@
+#pragma once
+#include <SFML/Graphics.hpp>
+#include "IGameBuilder.h"
+
+class GameBuilderDirector {
+private:
+	std::string m_window_title;
+	sf::VideoMode m_mode;
+	float m_dynamic_obj_ratio;
+	std::unique_ptr<IGameBuilder> m_ptr_builder;
+public:
+	GameBuilderDirector(std::unique_ptr<IGameBuilder>&& ptr_builder, const std::string& window_title, float dynamic_objects_ratio);
+	std::unique_ptr<IGameBuilder> build(IStateManager& state_manager);
+
+};
\ No newline at end of file
diff --git a/source/Builder/SimpleBuilder.h b/source/Builder/SimpleBuilder.h
index c2ac6f407272a7f347b627ae63caf6958f03c5e7..087e0e4200afc29bc8e9b114aff3b98ff263898f 100644
--- a/source/Builder/SimpleBuilder.h
+++ b/source/Builder/SimpleBuilder.h
@@ -3,6 +3,7 @@
 
 class SimpleBuilder:public CommonBuilder {
 public:
+	using CommonBuilder::CommonBuilder;
 	void create_rooms();
 	void set_rooms_sides();
 };
\ No newline at end of file
diff --git a/source/Command/ChangeStateCommand.cpp b/source/Command/ChangeStateCommand.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dcc36f69ac6a451d453e8d49945ddaea3b6e012c
--- /dev/null
+++ b/source/Command/ChangeStateCommand.cpp
@@ -0,0 +1,11 @@
+#include "ChangeStateCommand.h"
+
+
+void ExitCommand::execute() {
+    m_state_manager.set_next_state(std::make_unique<ExitState>(m_state_manager));
+}
+
+void GameCommand::execute() {
+    auto state = m_ptr_director->build(m_state_manager);
+    m_state_manager.set_next_state(std::move(state));
+}
\ No newline at end of file
diff --git a/source/Command/ChangeStateCommand.h b/source/Command/ChangeStateCommand.h
index 95c2ed8ed9e1f65a9d4808bdf692e37af085f69e..a5ce1db8e78c8e924408cb4189854f43ea45f5f5 100644
--- a/source/Command/ChangeStateCommand.h
+++ b/source/Command/ChangeStateCommand.h
@@ -1,21 +1,24 @@
 #pragma once
 #include "ISelectCommand.h"
 #include "./../State/IState.h"
+#include "./../Builder/GameBuilderDirector.h"
 
 class ChangeStateCommand : public ISelectCommand {
 public:
-	ChangeStateCommand(IStateManager& state_manager);
+	ChangeStateCommand(IStateManager& state_manager) : m_state_manager(state_manager) {};
 protected:
 	IStateManager& m_state_manager;
 };
 
 class ExitCommand : public ChangeStateCommand {
-
+	using ChangeStateCommand::ChangeStateCommand;
+	void execute() override;
 };
 
 class GameCommand : public ChangeStateCommand {
 public:
-	GameCommand(IStateManager& state_manager, std::unique_ptr<GameBuilderDirector> ptr_director)
+	GameCommand(IStateManager& state_manager, std::unique_ptr<GameBuilderDirector>&& ptr_director): ChangeStateCommand(state_manager), m_ptr_director(std::move(ptr_director)) {};
+	void execute() override;
 private:
 	std::unique_ptr<GameBuilderDirector> m_ptr_director;
 };
\ No newline at end of file
diff --git a/source/Command/ISelectCommand.cpp b/source/Command/ISelectCommand.cpp
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/source/Config/Config.h b/source/Config/Config.h
index 5fa4045d1a1759440f95452fce7acdfec01970b1..0b069ff2da531694f0948b78c8e8c1c91eb3a2d1 100644
--- a/source/Config/Config.h
+++ b/source/Config/Config.h
@@ -9,7 +9,6 @@ namespace config {
 	const sf::Vector2f BUTTON_SIZE = { 250, 100 };
 	const size_t BUTTON_FONT_SIZE = static_cast<size_t>(BUTTON_SIZE.y / 1.5f);
 	const float BUTTON_FRAME_THICKNESS = 2.0f;
-	const char FONT_FILE[] = "Calibri-Light.ttf";
 	const char SELECT_LEVEL_TITLE[] = "Select Level";
 	const sf::VideoMode SELECT_LEVEL_VIDEO_MODE{ 400, 600 };
 	const char BUTTON_TEXT_EASY[] = "Easy";
diff --git a/source/Draw/IPreparable.h b/source/Draw/IPreparable.h
index 0456a74101f7b6d2caf0d855d56c16450b4be279..143def2c068b2bde4604aa2ae078433764f7e65b 100644
--- a/source/Draw/IPreparable.h
+++ b/source/Draw/IPreparable.h
@@ -1,8 +1,7 @@
 #pragma once
 #include "./../Draw/IDrawable.h"
-#include <SFML/Graphics.hpp>
-#include "./../Command/ISelectCommand.h"
 
 class IPreparable :public IDrawable {
 	virtual void prepare_for_drawing() = 0;
+	virtual ~IPreparable() = default;
 };
\ No newline at end of file
diff --git a/source/Draw/MyFont.cpp b/source/Draw/MyFont.cpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7fe2bd947baf20a6f72c903220cf164a7bc3e486 100644
--- a/source/Draw/MyFont.cpp
+++ b/source/Draw/MyFont.cpp
@@ -0,0 +1,17 @@
+#include "MyFont.h"
+#include "./../Config/Config.h"
+
+MyFont::MyFont() {
+	if (!m_font.loadFromFile(std::string(FONT_PATH))) {
+		throw std::runtime_error("Cannot load file");
+	}
+}
+
+MyFont& MyFont::Instance() {
+	static MyFont instance;
+	return instance;
+}
+
+MyFont::operator const sf::Font& () const {
+	return m_font;
+}
diff --git a/source/Draw/MyFont.h b/source/Draw/MyFont.h
index 428602012b1fa9001715af47e1db49a6d7db302c..9d83da6e0f142c6409d9af3cdcf11f72dff912c3 100644
--- a/source/Draw/MyFont.h
+++ b/source/Draw/MyFont.h
@@ -1,10 +1,15 @@
 #pragma once
 #include <SFML/Graphics.hpp>
+#include "./../Config/Config.h"
 
 class MyFont {
+public:
+	MyFont(const MyFont&) = delete;
+	MyFont& operator = (const MyFont&) = delete;
+	static MyFont& Instance();
+	operator const sf::Font& () const;
 private:
-	sf::Font m_font;
 	MyFont();
-public:
-	Font& Instance();
-};
\ No newline at end of file
+private:
+	sf::Font m_font;
+};
diff --git a/source/Event/IGameEvent.h b/source/Event/IGameEvent.h
index b3b209b06f5a04631a05b87517d019628becf039..a5744ab85bdb720f5210b2bc19a3a722123b9316 100644
--- a/source/Event/IGameEvent.h
+++ b/source/Event/IGameEvent.h
@@ -1,5 +1,7 @@
 #pragma once
 #include "./../State/GameState.h"
+#include "./../Context/Context.h"
+
 
 class IGameEvent {
 public:
@@ -7,7 +9,7 @@ public:
     virtual ~IGameEvent() = default;
 };
 
-class DeleteStaticEntity {
+class DeleteStaticEntity: public IGameEvent {
 private:
     IStaticEntity* m_ptr_entity;
 public:
@@ -16,6 +18,11 @@ public:
 };
 
 class LostGame : public IGameEvent {
+public:
+    void handle(GameContext* context) override;
+};
+
+class WinGame : public IGameEvent {
 public:
     void handle(GameContext* context) override;
 };
\ No newline at end of file
diff --git a/source/Game/Pacman.h b/source/Game/Pacman.h
index 25eea5f42c0a6eaa36bccc6d3af17b8f9dd273a4..36234b7d5671d214c1419d11182f50a96f066529 100644
--- a/source/Game/Pacman.h
+++ b/source/Game/Pacman.h
@@ -3,6 +3,8 @@
 #include "./../Maze/Room.h"
 #include "IVisitor.h"
 
+
+
 class Pacman :public IEntity, public IVisitor {
 public:
 	void move(Room::Direction direction);
diff --git a/source/Maze/Maze.cpp b/source/Maze/Maze.cpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e0471d2baad26b3be613db21b7b4a548d9656092 100644
--- a/source/Maze/Maze.cpp
+++ b/source/Maze/Maze.cpp
@@ -0,0 +1,6 @@
+#include "Maze.h"
+
+void Maze::draw_into(sf::RenderWindow& window) {
+    for (auto& room : m_rooms)
+        room->draw_into(window);
+}
\ No newline at end of file
diff --git a/source/Maze/Maze.h b/source/Maze/Maze.h
index 8e0dc16016e5392a6c75aab3c4592d10bbc33619..f2e021cc86ed2356f137a23f51d27da47f3f55be 100644
--- a/source/Maze/Maze.h
+++ b/source/Maze/Maze.h
@@ -6,7 +6,9 @@
 
 class Maze : public IDrawable {
 public:
-	Maze(std::vector<std::unique_ptr<Room>>& rooms);
+	Maze() = default;
+	Maze(std::vector<std::unique_ptr<Room>>& rooms) : m_rooms(std::move(rooms)) {};
+	void draw_into(sf::RenderWindow& window) override;
 private:
 	std::vector<std::unique_ptr<Room>> m_rooms;
 };
\ No newline at end of file
diff --git a/source/Maze/Room.cpp b/source/Maze/Room.cpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..74d88766cfbd804d04cefde5f723fadccaee8585 100644
--- a/source/Maze/Room.cpp
+++ b/source/Maze/Room.cpp
@@ -0,0 +1,2 @@
+#include "Room.h"
+
diff --git a/source/Menu/Button.cpp b/source/Menu/Button.cpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3a54ab2c6f040595bab9e2d839cbb4553f4447d6 100644
--- a/source/Menu/Button.cpp
+++ b/source/Menu/Button.cpp
@@ -0,0 +1,51 @@
+#include "./../Config/Config.h"
+#include "./../Draw/MyFont.h"
+#include "Button.h"
+#include <iostream>
+
+Button::Button() {}
+
+void Button::set(sf::Vector2f pos, sf::Vector2f button_size, std::string text, \
+    size_t font_size) {
+//, std::unique_ptr<ISelectCommand>&& ptr_command
+    m_rectangle.setFillColor(config::BUTTON_COLOR_FILL);
+    m_rectangle.setSize(button_size);
+    m_rectangle.setOrigin(button_size.x / 2, button_size.y / 2);
+    m_rectangle.setPosition(pos);
+    m_text.setFont(MyFont::Instance());
+    m_text.setString(text);
+    m_text.setCharacterSize(font_size);
+    m_text.setLetterSpacing(1);
+    auto textRect = m_text.getLocalBounds();
+    m_text.setOrigin(textRect.left + textRect.width / 2.0f, textRect.top + textRect.height / 2.0f);
+    m_text.setPosition(pos);
+    m_text.setFillColor(config::BUTTON_COLOR_TEXT);
+    m_text.setOutlineColor(config::BUTTON_COLOR_FRAME);
+    m_text.setOutlineThickness(config::BUTTON_FRAME_THICKNESS);
+    //m_ptr_command = std::move(ptr_command);
+}
+
+void Button::select() {
+    m_rectangle.setFillColor(config::BUTTON_COLOR_SELECTION);
+}
+
+void Button::unselect() {
+    m_rectangle.setFillColor(config::BUTTON_COLOR_FILL);
+}
+
+bool Button::is_selectet() {
+    return m_is_selected;
+}
+
+bool Button::is_position_in(sf::Vector2f pos) {
+    return (m_rectangle.getGlobalBounds().contains(pos));
+}
+
+void Button::push() {
+    m_ptr_command->execute();
+}
+
+void Button::draw_into(sf::RenderWindow& window) const {
+    window.draw(m_rectangle);
+    window.draw(m_text);
+}
diff --git a/source/Menu/Button.h b/source/Menu/Button.h
index 22b5dceef9a2540e8910589b5dce56960283644d..de641440f510a6678ca4c212ca8d4ae432f33150 100644
--- a/source/Menu/Button.h
+++ b/source/Menu/Button.h
@@ -1,23 +1,25 @@
 #pragma once
 #include "./../Draw/IDrawable.h"
-#include <SFML/Graphics.hpp>
 #include "./../Command/ISelectCommand.h"
+#include <SFML/Graphics.hpp>
 
 
 
 class Button : public IDrawable {
 private:
 	sf::Text m_text;
-	bool m_selected = false;
+	bool m_is_selected = false;
 	sf::RectangleShape m_rectangle;
 	std::unique_ptr<ISelectCommand> m_ptr_command;
 public:
 	Button();
 	void set(sf::Vector2f pos, sf::Vector2f button_size, std::string text, \
-		size_t font_size, ISelectCommand ptr_command);
+		size_t font_size);
+	//, std::unique_ptr<ISelectCommand>&& ptr_command
 	void select();
 	void unselect();
-	bool is_unselectet();
-	void is_position_in(sf::Vector2f pos);
+	bool is_selectet();
+	bool is_position_in(sf::Vector2f pos);
 	void push();
+	void draw_into(sf::RenderWindow& window) const override;
 };
\ No newline at end of file
diff --git a/source/Menu/Menu.cpp b/source/Menu/Menu.cpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7390f01789951f477c9b948165e64546a7ed155a 100644
--- a/source/Menu/Menu.cpp
+++ b/source/Menu/Menu.cpp
@@ -0,0 +1,62 @@
+#include "Menu.h"
+#include "./../Config/Config.h"
+#include <iostream>
+//#include "./../Builder/ComplexBuilder.h"
+//#include "./../Builder/SimpleBuilder.h"
+//#include "./../Builder/GameBuilderDirector.h"
+//#include "./../Command/ChangeStateCommand.h"
+
+
+Menu::Menu(IStateManager& state_manager) {
+    float delta = 50;
+    sf::Vector2f starting_position(200, 30);
+
+    /*auto easy_director = std::make_unique<GameBuilderDirector>(
+        std::make_unique<SimpleBuilder>(
+            config::GAME_VIDEO_MODE.width, config::GAME_VIDEO_MODE.height,
+            config::ROOM_SIZE),
+        config::EASY_GAME_TITLE,
+        config::EASY_GAME_ENEMY_RATIO);
+
+    auto medium_director = std::make_unique<GameBuilderDirector>(
+        std::make_unique<SimpleBuilder>(
+            config::GAME_VIDEO_MODE.width, config::GAME_VIDEO_MODE.height,
+            config::ROOM_SIZE),
+        config::MEDIUM_GAME_TITLE,
+        config::MEDIUM_GAME_ENEMY_RATIO);
+
+    auto hard_director = std::make_unique<GameBuilderDirector>(
+        std::make_unique<ComplexBuilder>(
+            config::GAME_VIDEO_MODE.width, config::GAME_VIDEO_MODE.height,
+            config::ROOM_SIZE),
+        config::HARD_GAME_TITLE,
+        config::HARD_GAME_ENEMY_RATIO);
+
+    auto easy_command = std::make_unique<GameCommand>(state_manager, std::move(easy_director));
+    auto medium_command = std::make_unique<GameCommand>(state_manager, std::move(medium_director));
+    auto hard_command = std::make_unique<GameCommand>(state_manager, std::move(hard_director));
+    auto exit_command = std::make_unique<ExitCommand>(state_manager);*/
+    m_buttons[0].set(sf::Vector2f{ starting_position.x, starting_position.y + config::BUTTON_SIZE.y }, config::BUTTON_SIZE, config::BUTTON_TEXT_EASY, config::BUTTON_FONT_SIZE);//, std::move(easy_command));
+    m_buttons[1].set(sf::Vector2f{ starting_position.x, starting_position.y + 2 * config::BUTTON_SIZE.y}, config::BUTTON_SIZE, config::BUTTON_TEXT_MEDIUM, config::BUTTON_FONT_SIZE);//, std::move(medium_command));
+    m_buttons[2].set(sf::Vector2f{ starting_position.x, starting_position.y + 3 * config::BUTTON_SIZE.y}, config::BUTTON_SIZE, config::BUTTON_TEXT_HARD, config::BUTTON_FONT_SIZE);//, std::move(hard_command));
+    m_buttons[3].set(sf::Vector2f{ starting_position.x, starting_position.y + 4 * config::BUTTON_SIZE.y}, config::BUTTON_SIZE, config::BUTTON_TEXT_EXIT, config::BUTTON_FONT_SIZE);//, std::move(exit_command));
+    std::cout << "CREAAAAAAATE!\n";
+}
+
+
+void Menu::process_mouse(sf::Vector2f pos, bool is_pressed) {
+    for (auto& button : m_buttons) {
+        if (button.is_position_in(pos)) {
+            if (is_pressed) button.push();
+            else button.select();
+        }
+        else button.unselect();
+    }
+
+}
+
+void Menu::draw_into(sf::RenderWindow& window) const {
+    for (const Button& ptr_button : m_buttons) {
+        ptr_button.draw_into(window);
+    }
+}
\ No newline at end of file
diff --git a/source/Menu/Menu.h b/source/Menu/Menu.h
index 176cfc0ece86c0eeb294f92696ffcd5eeaaaa764..798c6b61f1a6a6048e1ea3214d86729fcd69e584 100644
--- a/source/Menu/Menu.h
+++ b/source/Menu/Menu.h
@@ -1,5 +1,5 @@
 #pragma once
-#include "./Application.h"
+#include "./../Application.h"
 #include "Button.h"
 #include <array>
 
@@ -11,4 +11,5 @@ private:
 public:
 	Menu(IStateManager& state_manager);
 	void process_mouse(sf::Vector2f pos, bool is_pressed);
+	void draw_into(sf::RenderWindow& window) const override;
 };
\ No newline at end of file
diff --git a/source/State/GameState.cpp b/source/State/GameState.cpp
index 8b137891791fe96927ad78e64b0aad7bded08bdc..3f0f245d81e680e6cf90a61efd8a080c42d0e58b 100644
--- a/source/State/GameState.cpp
+++ b/source/State/GameState.cpp
@@ -1 +1,117 @@
+#include "GameState.h"
+#include "./../Config/Config.h"
 
+GameState::GameState(IStateManager& state_manager, sf::VideoMode video_mode, std::string& window_title) : IState(state_manager), IWindowKeeper(video_mode, window_title) {}
+
+void GameState::do_step() {
+    event_handling();
+    update();
+    render();
+    return true;
+}
+
+void GameState::event_handling() {
+    sf::Event event;
+    while (m_window.pollEvent(event)) {
+        if (event.type == sf::Event::Closed) {
+            m_state_manager.set_next_state(std::make_unique<SelectLevelState>(m_state_manager, config::SELECT_LEVEL_TITLE));
+        }
+        if (event.type == sf::Event::KeyPressed && event.key.control && event.key.code == sf::Keyboard::Z) {
+            m_context_manager.restore_previous_context();
+        }
+
+        if (event.type == sf::Event::KeyPressed && m_context_manager.get_context()->state == GameContext::INGAME) {
+            process_key_pressed(event.key.code);
+        }
+    }
+}
+
+void GameState::update() {
+    if (m_context_manager.get_context()->state != GameContext::INGAME) {
+        return;
+    }
+
+    auto context = m_context_manager.get_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()) {
+            auto smth = std::make_unique<DeleteStaticEntity>(it);
+            smth->handle(m_context_manager.get_context());
+        }
+    }
+
+    for (auto it = context->dynamic_objects.begin(); it != context->dynamic_objects.end(); ++it) {
+        if (context->pacman.get_location() == (*it)->get_location()) {
+            auto smth_2 = std::make_unique<LostGame>();
+            smth_2->handle(m_context_manager.get_context());
+        }
+    }
+
+    if (!(context->static_objects.size())) {
+        m_events.emplace_back(std::move(std::make_unique<WinGame>()));
+        auto smth_3 = std::make_unique<WinGame>();
+        smth_3->handle(m_context_manager.get_context());
+    }
+}
+
+void GameState::render() {
+    auto context = m_context_manager.get_context();
+    switch (context->state) {
+    case GameContext::INGAME:
+        m_window.clear(config::GAME_COLOR_BACKGROUND_INGAME);
+        break;
+    case GameContext::LOST:
+        m_window.clear(config::GAME_COLOR_BACKGROUND_LOST);
+        break;
+    default:
+        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& el : context->dynamic_objects)
+        el->draw_into(m_window);
+
+    m_window.display();
+}
+
+
+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_context()->pacman.move(Room::UP);
+        break;
+
+    case sf::Keyboard::S:
+        m_context_manager.save_current_context();
+        m_context_manager.get_context()->pacman.move(Room::DOWN);
+        break;
+
+    case sf::Keyboard::A:
+        m_context_manager.save_current_context();
+        m_context_manager.get_context()->pacman.move(Room::LEFT);
+        break;
+    case sf::Keyboard::D:
+        m_context_manager.save_current_context();
+        m_context_manager.get_context()->pacman.move(Room::RIGHT);
+        break;
+    }
+}
+
+void GameState::set_maze(Maze&& maze) {
+    m_maze = std::move(maze);
+}
+
+void GameState::set_context(GameContext&& context) {
+    m_context_manager.set_context(std::move(context));
+    m_context_manager.save_current_context();
+}
\ No newline at end of file
diff --git a/source/State/GameState.h b/source/State/GameState.h
index 918f63dd08c93c8ebd12505220d102d976b28932..3fb1df5ddf42a22e04d49195c539ad235ee64ffb 100644
--- a/source/State/GameState.h
+++ b/source/State/GameState.h
@@ -6,15 +6,15 @@
 class GameState :public IState, public IWindowKeeper {
 private:
 	Maze m_maze;
-	ContextManager m_context;
+	ContextManager m_context_manager;
 public:
 	GameState(IStateManager& state_manager, sf::VideoMode video_mode, std::string& window_title);
 	void set_maze(Maze&& maze);
 	void set_context(GameContext&& context);
+	void do_step() override;
 private:
 	void event_handling() override;
 	void update() override;
 	void render() override;
-private:
-	Menu m_menu;
+	void process_key_pressed(sf::Keyboard::Key code);
 };
\ No newline at end of file
diff --git a/source/State/IState.cpp b/source/State/IState.cpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..946cb0349d99b4e802c3a47528b7c5a4469fab48 100644
--- a/source/State/IState.cpp
+++ b/source/State/IState.cpp
@@ -0,0 +1,3 @@
+#include "IState.h"
+
+IState::IState(IStateManager& state_manager): m_state_manager(state_manager) {}
\ No newline at end of file
diff --git a/source/State/IState.h b/source/State/IState.h
index 4cd9f0bd4e9a587ccf593e6549199d4734b17305..c2de5f4a2c5a13606c02f57b89d6218005143518 100644
--- a/source/State/IState.h
+++ b/source/State/IState.h
@@ -1,6 +1,6 @@
 #pragma once
 #include "IWindowKeeper.h"
-#include <iostream>
+
 
 class IStateManager;
 
@@ -13,8 +13,14 @@ protected:
     IStateManager& m_state_manager;
 };
 
+class IStateManager {
+public:
+    virtual void set_next_state(std::unique_ptr<IState> state) = 0;
+    virtual ~IStateManager() = default;
+};
+
 class ExitState : public IState {
 public:
     ExitState(IStateManager& state_manager) : IState(state_manager) {};
-    bool do_step() override {return false};
+    bool do_step() override { return false; }
 };
\ No newline at end of file
diff --git a/source/State/IWindowKeeper.cpp b/source/State/IWindowKeeper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a0c02b974bf0dc185d96e203d051d97ab79e0409
--- /dev/null
+++ b/source/State/IWindowKeeper.cpp
@@ -0,0 +1,7 @@
+#include "IWindowKeeper.h"
+#include "./../Config/Config.h"
+
+IWindowKeeper::IWindowKeeper(const sf::VideoMode& video_mode, const std::string& title) : m_window(video_mode, title) {
+	m_window.setFramerateLimit(config::FRAME_RATE_LIMIT);
+	m_window.setKeyRepeatEnabled(false);
+}
diff --git a/source/State/IWindowKeeper.h b/source/State/IWindowKeeper.h
index 43132b9d6a36481221d4bfb340da90b08273e4dd..953a8bab95e53fd91f995b5e2c372da80097ba2b 100644
--- a/source/State/IWindowKeeper.h
+++ b/source/State/IWindowKeeper.h
@@ -5,7 +5,7 @@ class IWindowKeeper {
 protected:
 	sf::RenderWindow m_window;
 public:
-	IWindowKeeper(sf::VideoMode video_mode, std::string& window_title) : m_window(video_mode, window_title) {};
+	IWindowKeeper(const sf::VideoMode& video_mode, const std::string& window_title);
 	virtual ~IWindowKeeper() = default;
 protected:
 	virtual void event_handling() = 0;
diff --git a/source/State/SelectState.cpp b/source/State/SelectState.cpp
index 5b3d0e831aed1e788e9c52a66ef3bd9108348964..a78a1d1616b7f5a19878369f45de8c2fce4b5bc5 100644
--- a/source/State/SelectState.cpp
+++ b/source/State/SelectState.cpp
@@ -1,3 +1,43 @@
 #include "SelectState.h"
+#include "./../Config/Config.h"
 #include <iostream>
 
+SelectState::SelectState(IStateManager& state_manager, const sf::VideoMode& video_mode, const std::string& window_title) :
+    IState{ state_manager }, IWindowKeeper{ video_mode , window_title }, m_menu{ state_manager } {
+}
+
+
+bool SelectState::do_step() {
+    event_handling();
+    update();
+    render();
+    return true;
+}
+
+
+void SelectState::event_handling() {
+    sf::Event event;
+    while (m_window.pollEvent(event)) {
+        if (event.type == sf::Event::Closed) {
+            m_state_manager.set_next_state(std::make_unique<ExitState>(m_state_manager));
+            break;
+        }
+    }
+}
+
+void SelectState::update() {
+    const sf::Vector2f pos = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
+    if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
+        m_menu.process_mouse(pos, true);
+        return;
+    }
+    m_menu.process_mouse({ static_cast<float>(pos.x), static_cast<float>(pos.y) }, false);
+
+}
+
+void SelectState::render() {
+    m_window.clear(config::SELECT_LEVEL_BACKGROUND_COLOR);
+    m_menu.draw_into(m_window);
+    m_window.display();
+
+}
\ No newline at end of file
diff --git a/source/State/SelectState.h b/source/State/SelectState.h
index add2553268bbf5a90d884792b24f8dccd51369db..7124224d27c6e2e1045abf936b96cb50b53b8e85 100644
--- a/source/State/SelectState.h
+++ b/source/State/SelectState.h
@@ -1,14 +1,12 @@
 #pragma once
 #include "IState.h"
-
+#include "./../Menu/Menu.h"
+#include "IWindowKeeper.h"
 
 class SelectState :public IState, public IWindowKeeper {
-private:
-	IStateManager& m_manager;
 public:
-	SelectState(IStateManager& state_manager, sf::VideoMode video_mode, std::string& window_title);
+	SelectState(IStateManager& state_manager, const sf::VideoMode& video_mode, const std::string& window_title);
 	bool do_step() override;
-private:
 	void event_handling() override;
 	void update() override;
 	void render() override;