diff --git a/source/BasicAbstractions/Command.h b/source/BasicAbstractions/Command.h
index b0082eb8a8cfbf5f0b51f124a02131df081571f3..9ec6a7be6b77dcc89e69262787aadfb6ee04b03a 100644
--- a/source/BasicAbstractions/Command.h
+++ b/source/BasicAbstractions/Command.h
@@ -1,6 +1,6 @@
 #pragma once
 
 struct ISelectCommand {
-  virtual void execute() = 0;
-  virtual ~ISelectCommand() = default;
+    virtual void execute() = 0;
+    virtual ~ISelectCommand() = default;
 };
\ No newline at end of file
diff --git a/source/States/ChangeStateCommand.h b/source/States/ChangeStateCommand.h
new file mode 100644
index 0000000000000000000000000000000000000000..d95f687fdd32ad98460ae34524bd38b7d6bde323
--- /dev/null
+++ b/source/States/ChangeStateCommand.h
@@ -0,0 +1,16 @@
+#pragma once
+#include "../BasicAbstractions/Command.h"
+#include "../Application/IState.h"
+#include "ExitState/ExitState.h"
+
+struct ChangeStateCommand : ISelectCommand {
+    explicit ChangeStateCommand(IStateManager& state_manager) : m_state_manager(state_manager) {}
+protected:
+    IStateManager& m_state_manager;
+};
+
+struct ExitCommand : ChangeStateCommand {
+    using ChangeStateCommand::ChangeStateCommand;
+    void execute() override { m_state_manager.set_next_state(std::make_unique<ExitState>(m_state_manager)); }
+};
+
diff --git a/source/States/ExitState/ExitState.h b/source/States/ExitState/ExitState.h
index 26508f03574852ab17c21c8cc93f3eb0c45de4a0..22ce415cccb9648efc109dcd25aba17605315fcb 100644
--- a/source/States/ExitState/ExitState.h
+++ b/source/States/ExitState/ExitState.h
@@ -1,12 +1,7 @@
 #pragma once
-#include <iostream> /// @todo remove it
 #include "../../Application/IState.h"
-#include "../../Application/IWindowKeeper.h"
 
 struct ExitState : IState {
-    explicit ExitState(IStateManager& state_manager) : IState(state_manager) {}
-    bool do_step() override {
-        std::cout << "Exiting..." << std::endl;
-        return false;
-    }
+    using IState::IState;
+    bool do_step() override { return false; }
 };
\ No newline at end of file
diff --git a/source/States/SelectState/SelectState.cpp b/source/States/SelectState/SelectState.cpp
index d849f725b89c87bd0853d01065b5426f6fe0646e..769204951bdb95b34daac4530f33382f2ad97b19 100644
--- a/source/States/SelectState/SelectState.cpp
+++ b/source/States/SelectState/SelectState.cpp
@@ -1,14 +1,9 @@
 #include "SelectState.h"
-#include "../ExitState/ExitState.h"
+#include "../ChangeStateCommand.h"
 #include "../../Configuration.h"
 #include "../../BasicAbstractions/Font.h"
 
-void Button::draw_into(sf::RenderWindow& window) const {
-    window.draw(m_rectangle);
-    window.draw(m_text);
-}
-
-void Button::set(const sf::Vector2f pos, const sf::Vector2f size, const std::string& text, const size_t font_size) {//, std::shared_ptr<ISelectCommand> ptr_command) {
+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);
     m_rectangle.setPosition(pos);
     m_rectangle.setFillColor(config::BUTTON_COLOR_FILL);
@@ -25,6 +20,7 @@ void Button::set(const sf::Vector2f pos, const sf::Vector2f size, const std::str
         round(button_pos.x + (button_size.x - text_bounds.width) / 2 - text_bounds.left),
         round(button_pos.y + (button_size.y - text_bounds.height) / 2 - text_bounds.top)
     );
+    m_ptr_command = std::move(ptr_command);
 }
 
 void Button::select() {
@@ -40,26 +36,41 @@ bool Button::is_position_in(const sf::Vector2f pos) const {
         && pos.y >= m_rectangle.getPosition().y && pos.y <= (m_rectangle.getPosition().y + m_rectangle.getSize().y);
 }
 
+void Button::push() const {
+    m_ptr_command->execute();
+}
+
+void Button::draw_into(sf::RenderWindow& window) const {
+    window.draw(m_rectangle);
+    window.draw(m_text);
+}
+
 Menu::Menu(IStateManager& state_manager) {
     const float pos_left = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.width) - config::BUTTON_SIZE.x) / 2;
     const float pos_diff = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y * 4) / 10;
     const float pos_top = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y*4 - pos_diff*3) / 2;
-    m_buttons[0].set(sf::Vector2f{pos_left, pos_top},
-        config::BUTTON_SIZE, config::BUTTON_TEXT_EASY, config::BUTTON_FONT_SIZE);
-    m_buttons[1].set(sf::Vector2f{pos_left, pos_top + config::BUTTON_SIZE.y + pos_diff},
-        config::BUTTON_SIZE, config::BUTTON_TEXT_MEDIUM, config::BUTTON_FONT_SIZE);
-    m_buttons[2].set(sf::Vector2f{pos_left, pos_top + 2*(config::BUTTON_SIZE.y + pos_diff)},
-        config::BUTTON_SIZE, config::BUTTON_TEXT_HARD, config::BUTTON_FONT_SIZE);
-    m_buttons[3].set(sf::Vector2f{pos_left, pos_top + 3*(config::BUTTON_SIZE.y + pos_diff)},
-        config::BUTTON_SIZE, config::BUTTON_TEXT_EXIT, config::BUTTON_FONT_SIZE);
+    m_buttons[0].set(sf::Vector2f{pos_left, pos_top}, config::BUTTON_SIZE, config::BUTTON_TEXT_EASY,
+        config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager));
+    m_buttons[1].set(sf::Vector2f{pos_left, pos_top + config::BUTTON_SIZE.y + pos_diff}, config::BUTTON_SIZE,
+     config::BUTTON_TEXT_MEDIUM, config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager));
+    m_buttons[2].set(sf::Vector2f{pos_left, pos_top + 2*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE,
+     config::BUTTON_TEXT_HARD, config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager));
+    m_buttons[3].set(sf::Vector2f{pos_left, pos_top + 3*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE,
+     config::BUTTON_TEXT_EXIT, config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager));
 }
 
-void Menu::process_mouse(const sf::Vector2f pos, bool is_pressed) {
+bool Menu::process_mouse(const sf::Vector2f pos, const bool is_pressed) {
     for (auto& button : m_buttons) {
-        if (button.is_position_in(pos))
+        if (button.is_position_in(pos)) {
             button.select();
+            if (is_pressed) {
+                button.push();
+                return false;
+            }
+        }
         else button.unselect();
     }
+    return true;
 }
 
 void Menu::draw_into(sf::RenderWindow& window) const {
@@ -79,7 +90,9 @@ void SelectState::event_handling() {
 }
 
 void SelectState::update() {
-    m_menu.process_mouse(m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window)), true);
+    if (!m_menu.process_mouse(m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window)),
+        sf::Mouse::isButtonPressed(sf::Mouse::Left)))
+        m_window.close();
 }
 
 void SelectState::render() {
diff --git a/source/States/SelectState/SelectState.h b/source/States/SelectState/SelectState.h
index 1c793286c525feb64f88b736b71f9211ee367162..063d351b457110979831466cd74f982435ecda28 100644
--- a/source/States/SelectState/SelectState.h
+++ b/source/States/SelectState/SelectState.h
@@ -7,22 +7,22 @@
 class Button: public IDrawable {
 public:
     Button() = default;
-    void set(sf::Vector2f pos, sf::Vector2f size, const std::string& text, size_t font_size);//, std::shared_ptr<ISelectCommand> ptr_command);
+    void set(sf::Vector2f pos, sf::Vector2f size, const std::string& text, size_t font_size, std::unique_ptr<ISelectCommand> ptr_command);
     void select();
     void unselect();
     bool is_position_in(sf::Vector2f pos) const;
-    // void push();
+    void push() const;
     void draw_into(sf::RenderWindow& window) const override;
 private:
     sf::Text m_text;
     sf::RectangleShape m_rectangle;
-    //std::shared_ptr<ISelectCommand> m_ptr_command; /// @todo shared_ptr?
+    std::unique_ptr<ISelectCommand> m_ptr_command;
 };
 
 class Menu: public IDrawable {
 public:
     explicit Menu(IStateManager& state_manager);
-    void process_mouse(sf::Vector2f pos, bool is_pressed);
+    bool process_mouse(sf::Vector2f pos, bool is_pressed);
     void draw_into(sf::RenderWindow& window) const override;
 private:
     std::array<Button, 4> m_buttons;