diff --git a/source/Application/Application.h b/source/Application/Application.h
index a8131705b16ab3c9c2220578afb3b30dbbef9178..0900b6f36d9deb779856fcd632629c8a8f5fb55a 100644
--- a/source/Application/Application.h
+++ b/source/Application/Application.h
@@ -1,7 +1,7 @@
 #pragma once
 #include <States/SelectState/SelectState.h>
 
-class Application : public IStateManager {
+class Application final : public IStateManager {
 public:
     Application() = default;
     int run();
diff --git a/source/BasicAbstractions/Button/Button.h b/source/BasicAbstractions/Button/Button.h
index add9902a1bca7d894cfda77410bddff5fb2353e2..5695c945dd7f5352d7c514272038b9b7c4b32ec3 100644
--- a/source/BasicAbstractions/Button/Button.h
+++ b/source/BasicAbstractions/Button/Button.h
@@ -2,7 +2,7 @@
 #include <BasicAbstractions/Command.h>
 #include <BasicAbstractions/IDrawable.h>
 
-class Button: public IDrawable {
+class Button final : public IDrawable {
 public:
     Button() = default;
     void set(sf::Vector2f pos, sf::Vector2f size, const std::string& text, size_t font_size, std::unique_ptr<ISelectCommand> ptr_command);
diff --git a/source/BasicAbstractions/Font.h b/source/BasicAbstractions/Font.h
index 4fd6264e204ab1865cf71b6823b3a6536de733fb..d77f0278ab1391834d30f19972f3244bab1cbe0f 100644
--- a/source/BasicAbstractions/Font.h
+++ b/source/BasicAbstractions/Font.h
@@ -1,7 +1,7 @@
 #pragma once
 #include <Configuration.h>
 
-class MyFont {
+class MyFont final {
 public:
     static sf::Font& Instance() {
         static MyFont instance;
diff --git a/source/Configuration.h b/source/Configuration.h
index 676104d9739487491dea6bfd5ed82d6f9f11f5e0..84d12d486724d3b061f0fc3970c18a20e81efd5d 100644
--- a/source/Configuration.h
+++ b/source/Configuration.h
@@ -5,7 +5,7 @@ namespace config {
     // Общее:
     constexpr unsigned int FRAME_RATE_LIMIT = 60;
     // Меню:
-    const sf::Vector2f BUTTON_SIZE = { 250, 100 };
+    const sf::Vector2f BUTTON_SIZE = { 250, 80 };
     const size_t BUTTON_FONT_SIZE = static_cast<size_t>(BUTTON_SIZE.y / 1.5f);
     constexpr float BUTTON_FRAME_THICKNESS = 2.0f;
     constexpr char FONT_FILE[] = ASSETS_PATH "calibril.ttf";
@@ -14,6 +14,7 @@ namespace config {
     constexpr char BUTTON_TEXT_EASY[] = "Easy";
     constexpr char BUTTON_TEXT_MEDIUM[] = "Medium";
     constexpr char BUTTON_TEXT_HARD[] = "Hard";
+    constexpr char BUTTON_TEXT_EXTREME[] = "Extreme";
     constexpr char BUTTON_TEXT_EXIT[] = "Exit";
     // Игра:
     const sf::VideoMode GAME_VIDEO_MODE{ 1080, 720 };
@@ -25,7 +26,7 @@ namespace config {
     constexpr float HARD_GAME_ENEMY_RATIO = 0.07f;
     constexpr float ROOM_SIZE = 50;
     constexpr float GAME_ENEMY_SIZE = ROOM_SIZE * 0.7;
-    constexpr float GAME_FOOD_SIZE = ROOM_SIZE * 0.2;
+    constexpr float GAME_FOOD_SIZE = ROOM_SIZE * 0.1;
     // Пакмэн:
     constexpr float GAME_PACMAN_SIZE = ROOM_SIZE * 0.8;
     // constexpr sf::Keyboard::Key KEY_LEFT = sf::Keyboard::A;
diff --git a/source/States/ExitState/ExitState.h b/source/States/ExitState/ExitState.h
index f886cd477ae2ee422abd660909c72d7cac7741ef..ed914a58a827ca41e8db61f5bf3df5a252b5e5eb 100644
--- a/source/States/ExitState/ExitState.h
+++ b/source/States/ExitState/ExitState.h
@@ -1,7 +1,7 @@
 #pragma once
 #include <BasicAbstractions/IState.h>
 
-struct ExitState : IState {
+struct ExitState final : IState {
     using IState::IState;
     bool do_step() noexcept override { return false; }
 };
\ No newline at end of file
diff --git a/source/States/GameState/Context/ContextManager.h b/source/States/GameState/Context/ContextManager.h
index 9c84bc30e733ecb8eed251223d9a133dde5f42dc..8ad7e9fff1a317626ed059071a803c42e4e739c4 100644
--- a/source/States/GameState/Context/ContextManager.h
+++ b/source/States/GameState/Context/ContextManager.h
@@ -2,7 +2,7 @@
 #include <States/GameState/Context/GameContext.h>
 #include <stack>
 
-class ContextManager {
+class ContextManager final {
 public:
     void reset(GameContext&& context);
     GameContext& get_current_context() { return m_contexts.top(); }
diff --git a/source/States/GameState/Context/GameContext.h b/source/States/GameState/Context/GameContext.h
index 81b3bdcc9c0e77154640bea2b3982b7655218652..21022b24c28f94eb895a5fb651ff3071c7ac94de 100644
--- a/source/States/GameState/Context/GameContext.h
+++ b/source/States/GameState/Context/GameContext.h
@@ -3,7 +3,7 @@
 #include <States/GameState/Entities/StaticEntities/StaticEntities.h>
 #include <States/GameState/Entities/DynamicEntities/DynamicEntities.h>
 
-struct GameContext {
+struct GameContext final {
     [[nodiscard]] GameContext clone() const;
     Pacman pacman;
     std::vector<std::unique_ptr<IStaticEntity>> static_objects;
diff --git a/source/States/GameState/Entities/DynamicEntities/DynamicEntities.h b/source/States/GameState/Entities/DynamicEntities/DynamicEntities.h
index b8be73931b175e773424e100382a1f54838eb789..2033a0feaf4ece6ab25ef6bf5a7528bbfcb7dc1c 100644
--- a/source/States/GameState/Entities/DynamicEntities/DynamicEntities.h
+++ b/source/States/GameState/Entities/DynamicEntities/DynamicEntities.h
@@ -8,7 +8,7 @@ struct IDynamicEntity : IEntity {
     ~IDynamicEntity() override = default;
 };
 
-class Enemy : public IDynamicEntity {
+class Enemy final : public IDynamicEntity {
 public:
     Enemy();
     [[nodiscard]] std::unique_ptr<IDynamicEntity> clone() const override;
diff --git a/source/States/GameState/Entities/Pacman/Pacman.h b/source/States/GameState/Entities/Pacman/Pacman.h
index 827fb79fe838133bf7891926f27bebc8d81f196a..03772e0dec6ae8b8476babf029767ee61bb8c23c 100644
--- a/source/States/GameState/Entities/Pacman/Pacman.h
+++ b/source/States/GameState/Entities/Pacman/Pacman.h
@@ -1,7 +1,7 @@
 #pragma once
 #include <States/GameState/Entities/IEntity.h>
 
-class Pacman : public IEntity {
+class Pacman final : public IEntity {
 public:
     Pacman();
     void move(Room::Direction direction);
diff --git a/source/States/GameState/Entities/StaticEntities/StaticEntities.h b/source/States/GameState/Entities/StaticEntities/StaticEntities.h
index d005d7d7c7b64bb61d10fa1e88928809c6a59a77..193f3fc32463a59f4a0782272bc6d513b83fae27 100644
--- a/source/States/GameState/Entities/StaticEntities/StaticEntities.h
+++ b/source/States/GameState/Entities/StaticEntities/StaticEntities.h
@@ -6,7 +6,7 @@ struct IStaticEntity : IEntity {
    ~IStaticEntity() override = default;
 };
 
-class Food : public IStaticEntity {
+class Food final : public IStaticEntity {
 public:
     Food();
     [[nodiscard]] std::unique_ptr<IStaticEntity> clone() const override;
diff --git a/source/States/GameState/GameBuilder/GameBuilder.cpp b/source/States/GameState/GameBuilder/GameBuilder.cpp
index 0c4502f27756ac79d5cf6001cf8d4935990093a1..db301b6a9822b860a111f9aff6c97418c2e5a71a 100644
--- a/source/States/GameState/GameBuilder/GameBuilder.cpp
+++ b/source/States/GameState/GameBuilder/GameBuilder.cpp
@@ -57,7 +57,7 @@ void SimpleBuilder::create_rooms() {
     const auto number_of_rooms_in_row = static_cast<size_t>(m_width / m_room_size),
         number_of_rooms_in_col = static_cast<size_t>(m_height / m_room_size);
 
-    sf::Vector2f gap(
+    const sf::Vector2f gap(
         (m_width - static_cast<float>(number_of_rooms_in_row) * m_room_size + m_room_size) / 2.f,
         (m_height - static_cast<float>(number_of_rooms_in_col) * m_room_size + m_room_size) / 2.f
     );
@@ -78,8 +78,8 @@ void SimpleBuilder::create_rooms() {
 void SimpleBuilder::set_rooms_sides() {
     if (m_rooms.empty()) return;
     if (m_rooms[0].empty()) return;
-    for (size_t i = 0; i < m_rooms[0].size(); ++i)
-        m_rooms[0][i]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[0][i]));
+    for (const auto & room : m_rooms[0])
+        room->set_side(Room::UP, std::make_shared<Wall>(*room));
     m_rooms[0][0]->set_side(Room::LEFT, std::make_shared<Wall>(*m_rooms[0][0]));
     for (size_t i = 1; i < m_rooms[0].size() - 1; ++i) {
         auto tmp_side_ptr = std::make_shared<Pass>(*m_rooms[0][i], *m_rooms[0][i-1]);
@@ -110,19 +110,122 @@ void SimpleBuilder::set_rooms_sides() {
     }
 }
 
-ComplexBuilder::ComplexBuilder(const float width, const float height, const float room_size, const sf::Color room_color) :
+void ComplexBuilder::create_rooms() {
+    const auto number_of_rooms_in_row = static_cast<size_t>(m_width / m_room_size),
+        number_of_rooms_in_col = static_cast<size_t>(m_height / m_room_size);
+
+    const sf::Vector2f gap(
+        (m_width - static_cast<float>(number_of_rooms_in_row) * m_room_size + m_room_size) / 2.f,
+        (m_height - static_cast<float>(number_of_rooms_in_col) * m_room_size + m_room_size) / 2.f
+    );
+
+    for (size_t i = 0; i < number_of_rooms_in_col; ++i) {
+        std::vector<std::unique_ptr<Room>> room_row;
+        room_row.reserve(number_of_rooms_in_row);
+        for (size_t j = 0; j < number_of_rooms_in_row; ++j) {
+            if (i % 2 == 0 && j % 2 == 0) continue;
+            auto tmp_room = std::make_unique<Room>(m_room_size);
+            tmp_room->set_color(m_room_color);
+            tmp_room->set_position(gap + sf::Vector2f{ m_room_size * static_cast<float>(j), m_room_size * static_cast<float>(i) });
+            room_row.emplace_back(std::move(tmp_room));
+        }
+        m_rooms.emplace_back(std::move(room_row));
+    }
+}
+
+void ComplexBuilder::set_rooms_sides() {
+    if (m_rooms.empty()) return;
+    if (m_rooms[0].empty()) return;
+    for (size_t i = 0; i < m_rooms.size(); i+=2) {
+        for (const auto & room : m_rooms[i]) {
+            room->set_side(Room::LEFT, std::make_shared<Wall>(*room));
+            room->set_side(Room::RIGHT, std::make_shared<Wall>(*room));
+        }
+    }
+    for (const auto & room : m_rooms[0])
+        room->set_side(Room::UP, std::make_shared<Wall>(*room));
+    for (size_t i = 1; i < m_rooms.size() - 1; i+=2) {
+        m_rooms[i][0]->set_side(Room::LEFT, std::make_shared<Wall>(*m_rooms[i][0]));
+        m_rooms[i][0]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[i][0]));
+        m_rooms[i][0]->set_side(Room::DOWN, std::make_shared<Wall>(*m_rooms[i][0]));
+        for (size_t j = 1; j < m_rooms[i].size() - 1; ++j) {
+            if (j % 2 == 0) {
+                m_rooms[i][j]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[i][j]));
+                m_rooms[i][j]->set_side(Room::DOWN, std::make_shared<Wall>(*m_rooms[i][j]));
+                continue;
+            }
+            auto side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][j], *m_rooms[i-1][j-j/2-1]);
+            m_rooms[i][j]->set_side(Room::UP, side_ptr_temp);
+            m_rooms[i-1][j-j/2-1]->set_side(Room::DOWN, side_ptr_temp);
+            side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][j], *m_rooms[i][j-1]);
+            m_rooms[i][j]->set_side(Room::LEFT, side_ptr_temp);
+            m_rooms[i][j-1]->set_side(Room::RIGHT, side_ptr_temp);
+            side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][j], *m_rooms[i][j+1]);
+            m_rooms[i][j]->set_side(Room::RIGHT, side_ptr_temp);
+            m_rooms[i][j+1]->set_side(Room::LEFT, side_ptr_temp);
+            side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][j], *m_rooms[i+1][j-j/2-1]);
+            m_rooms[i][j]->set_side(Room::DOWN, side_ptr_temp);
+            m_rooms[i+1][j-j/2-1]->set_side(Room::UP, side_ptr_temp);
+        }
+        if (m_rooms[i].size() % 2 == 1) {
+            m_rooms[i][m_rooms[i].size()-1]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[i][m_rooms[i].size()-1]));
+            m_rooms[i][m_rooms[i].size()-1]->set_side(Room::DOWN, std::make_shared<Wall>(*m_rooms[i][m_rooms[i].size()-1]));
+        }
+        else {
+            auto side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][m_rooms[i].size()-1], *m_rooms[i][m_rooms[i].size()-2]);
+            m_rooms[i][m_rooms[i].size()-1]->set_side(Room::LEFT, side_ptr_temp);
+            m_rooms[i][m_rooms[i].size()-2]->set_side(Room::RIGHT, side_ptr_temp);
+            side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][m_rooms[i].size()-1], *m_rooms[i-1][m_rooms[i].size()-1]);
+            m_rooms[i][m_rooms[i].size()-1]->set_side(Room::UP, side_ptr_temp);
+            m_rooms[i-1][m_rooms[i].size()-1]->set_side(Room::DOWN, side_ptr_temp);
+        }
+        m_rooms[i][m_rooms[i].size()-1]->set_side(Room::RIGHT, std::make_shared<Wall>(*m_rooms[i][m_rooms[i].size()-1]));
+    }
+    for (auto& room : m_rooms[m_rooms.size()-1])
+        room->set_side(Room::DOWN, std::make_shared<Wall>(*room));
+    if (m_rooms.size() % 2 == 0) {
+        m_rooms[m_rooms.size()-1][0]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][0]));
+        m_rooms[m_rooms.size()-1][0]->set_side(Room::LEFT, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][0]));
+        for (size_t i = 1; i < m_rooms[m_rooms.size()-1].size() - 1; ++i) {
+            if (i % 2 == 0) {
+                m_rooms[m_rooms.size()-1][i]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][i]));
+                continue;
+            }
+            auto side_ptr_temp = std::make_shared<Pass>(*m_rooms[m_rooms.size()-1][i], *m_rooms[m_rooms.size()-2][i-i/2-1]);
+            m_rooms[m_rooms.size()-1][i]->set_side(Room::UP, side_ptr_temp);
+            m_rooms[m_rooms.size()-2][i-i/2-1]->set_side(Room::DOWN, side_ptr_temp);
+            side_ptr_temp = std::make_shared<Pass>(*m_rooms[m_rooms.size()-1][i-1], *m_rooms[m_rooms.size()-1][i]);
+            m_rooms[m_rooms.size()-1][i]->set_side(Room::LEFT, side_ptr_temp);
+            m_rooms[m_rooms.size()-1][i-1]->set_side(Room::RIGHT, side_ptr_temp);
+            side_ptr_temp = std::make_shared<Pass>(*m_rooms[m_rooms.size()-1][i+1], *m_rooms[m_rooms.size()-1][i]);
+            m_rooms[m_rooms.size()-1][i]->set_side(Room::RIGHT, side_ptr_temp);
+            m_rooms[m_rooms.size()-1][i+1]->set_side(Room::LEFT, side_ptr_temp);
+        }
+        if (m_rooms[m_rooms.size()-1].size() % 2 == 1) {
+            m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1]));
+        }
+        else {
+            auto side_ptr_temp = std::make_shared<Pass>(*m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1], *m_rooms[m_rooms.size()-2][m_rooms[m_rooms.size()-1].size()-1]);
+            m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1]->set_side(Room::UP, side_ptr_temp);
+            m_rooms[m_rooms.size()-2][m_rooms[m_rooms.size()-1].size()-1]->set_side(Room::DOWN, side_ptr_temp);
+        }
+        m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1]->set_side(Room::RIGHT, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1]));
+    }
+}
+
+ComplexRandomBuilder::ComplexRandomBuilder(const float width, const float height, const float room_size, const sf::Color room_color) :
     CommonBuilder(width, height, room_size, room_color),
     m_rooms_grid(static_cast<size_t>(height / m_room_size), std::vector(static_cast<size_t>(width / m_room_size), false)),
     m_number_of_rooms_in_row(static_cast<size_t>(width / m_room_size)),
     m_number_of_rooms_in_col(static_cast<size_t>(height / m_room_size)),
     gen(rd()) {}
 
-bool ComplexBuilder::is_valid(const int x, const int y) const {
+bool ComplexRandomBuilder::is_valid(const int x, const int y) const {
     if (x >= m_number_of_rooms_in_row || y >= m_number_of_rooms_in_col || x < 0 || y < 0) return false;
     return true;
 }
 
-void ComplexBuilder::collapse_function() {
+void ComplexRandomBuilder::collapse_function() {
     std::uniform_int_distribution<size_t> row_dist(0, m_number_of_rooms_in_row-1);
     std::uniform_int_distribution<size_t> col_dist(0, m_number_of_rooms_in_col-1);
     std::normal_distribution prob_dist(0.67f, 0.25f);
@@ -162,7 +265,7 @@ void ComplexBuilder::collapse_function() {
     }
 }
 
-void ComplexBuilder::create_rooms() {
+void ComplexRandomBuilder::create_rooms() {
     collapse_function();
 
     const sf::Vector2f gap(
@@ -189,7 +292,7 @@ void ComplexBuilder::create_rooms() {
     }
 }
 
-void ComplexBuilder::set_rooms_sides() {
+void ComplexRandomBuilder::set_rooms_sides() {
     for (size_t i = 0; i < m_number_of_rooms_in_col; ++i) {
         for (size_t j = 0; j < m_number_of_rooms_in_row; ++j) {
             if (!m_rooms_grid[i][j]) continue;
diff --git a/source/States/GameState/GameBuilder/GameBuilder.h b/source/States/GameState/GameBuilder/GameBuilder.h
index eee5204c7514df8cd1b08e4e877524fdad3ccea6..3188076538ff2f2eb482141b8e5212d95ba7e415 100644
--- a/source/States/GameState/GameBuilder/GameBuilder.h
+++ b/source/States/GameState/GameBuilder/GameBuilder.h
@@ -31,15 +31,21 @@ protected:
     std::unique_ptr<GameState> m_game_state;
 };
 
-struct SimpleBuilder : CommonBuilder {
+struct SimpleBuilder final : CommonBuilder {
     using CommonBuilder::CommonBuilder;
     void create_rooms() override;
     void set_rooms_sides() override;
 };
 
-class ComplexBuilder : public CommonBuilder {
+struct ComplexBuilder final : CommonBuilder {
+    using CommonBuilder::CommonBuilder;
+    void create_rooms() override;
+    void set_rooms_sides() override;
+};
+
+class ComplexRandomBuilder final : public CommonBuilder {
 public:
-    ComplexBuilder(float width, float height, float room_size, sf::Color room_color);
+    ComplexRandomBuilder(float width, float height, float room_size, sf::Color room_color);
     void create_rooms() override;
     void set_rooms_sides() override;
 private:
diff --git a/source/States/GameState/GameBuilder/GameBuilderDirector.h b/source/States/GameState/GameBuilder/GameBuilderDirector.h
index 0f39088ba551d96c2d03af616331b4973ea6ab0e..407f38d5fe79c6e771f930d06a6f90db590d4a7f 100644
--- a/source/States/GameState/GameBuilder/GameBuilderDirector.h
+++ b/source/States/GameState/GameBuilder/GameBuilderDirector.h
@@ -1,7 +1,7 @@
 #pragma once
 #include <States/GameState/GameBuilder/GameBuilder.h>
 
-class GameBuilderDirector {
+class GameBuilderDirector final {
 public:
     GameBuilderDirector(std::unique_ptr<IGameBuilder>&& ptr_builder, const sf::VideoMode& mode, std::string  window_title, const float dynamic_object_ratio) :
         m_window_title(std::move(window_title)), m_mode(mode), m_dynamic_object_ratio(dynamic_object_ratio), m_ptr_builder(std::move(ptr_builder)) {}
diff --git a/source/States/GameState/GameState.h b/source/States/GameState/GameState.h
index 16359aac7ccdfb5270545082b1216258bc529d4c..cc5a479a0a04945acfffb03647063ef49bb8ea9f 100644
--- a/source/States/GameState/GameState.h
+++ b/source/States/GameState/GameState.h
@@ -5,7 +5,7 @@
 #include <States/GameState/Maze/Maze.h>
 #include <States/GameState/Context/ContextManager.h>
 
-class GameState : public IState, public IWindowKeeper {
+class GameState final : public IState, public IWindowKeeper {
 public:
     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/Maze/Maze.h b/source/States/GameState/Maze/Maze.h
index ee9937995aed94fbd70417758bebd560808eb98e..e6d29e6e5c1e5561102c9a315e86c0d2d84a5496 100644
--- a/source/States/GameState/Maze/Maze.h
+++ b/source/States/GameState/Maze/Maze.h
@@ -4,7 +4,7 @@
 
 #include <vector>
 
-class Maze : public IDrawable {
+class Maze final : public IDrawable {
 public:
     Maze() = default;
     explicit Maze(std::vector<std::unique_ptr<Room>>&& rooms) : m_rooms(std::move(rooms)) {}
diff --git a/source/States/GameState/Maze/Room/Room.h b/source/States/GameState/Maze/Room/Room.h
index 844107c06e132d370a97db02479004de47fa3ca7..a6780f31f18009b253db9faceba1b9c197d166af 100644
--- a/source/States/GameState/Maze/Room/Room.h
+++ b/source/States/GameState/Maze/Room/Room.h
@@ -7,7 +7,7 @@
 
 struct IRoomSide;
 
-class Room: public IDrawable {
+class Room final : public IDrawable {
 public:
     enum Direction { INVALID = -1, LEFT, RIGHT, UP, DOWN };
     explicit Room(float size);
diff --git a/source/States/GameState/Maze/Room/RoomSide/RoomSide.h b/source/States/GameState/Maze/Room/RoomSide/RoomSide.h
index 411fc35af015d66f7b82ed142904bc5ed464aa3c..07a452bf3086d78235bbaabe5974d0482234e32a 100644
--- a/source/States/GameState/Maze/Room/RoomSide/RoomSide.h
+++ b/source/States/GameState/Maze/Room/RoomSide/RoomSide.h
@@ -9,7 +9,7 @@ struct IRoomSide : IPreparable {
     ~IRoomSide() override = default;
 };
 
-class Pass : public IRoomSide {
+class Pass final : public IRoomSide {
 public:
     explicit Pass(Room& room1, Room& room2) : m_room1(room1), m_room2(room2) {}
     void enter(IEntity* entity) const override;
@@ -20,7 +20,7 @@ private:
     Room& m_room2;
 };
 
-class Wall : public IRoomSide {
+class Wall final : public IRoomSide {
 public:
     explicit Wall(Room& room) : m_room(room) {}
     void enter(IEntity* entity) const override {}
diff --git a/source/States/SelectState/SelectState.cpp b/source/States/SelectState/SelectState.cpp
index 28fa92909062882f8a4f9e13cc3ba953ea0a6503..83326596186b0619d9b5f714a3fdc97eebc45384 100644
--- a/source/States/SelectState/SelectState.cpp
+++ b/source/States/SelectState/SelectState.cpp
@@ -4,8 +4,8 @@
 
 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;
+    const float pos_diff = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y * 5) / 10;
+    const float pos_top = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y*5 - pos_diff*4) / 2;
 
     auto easy_level_command = std::make_unique<GameCommand>(
         state_manager,
@@ -31,6 +31,14 @@ Menu::Menu(IStateManager& state_manager) {
             config::HARD_GAME_TITLE,
             config::HARD_GAME_ENEMY_RATIO));
 
+    auto extreme_level_command = std::make_unique<GameCommand>(
+        state_manager,
+        std::make_unique<GameBuilderDirector>(
+            std::make_unique<ComplexRandomBuilder>(config::GAME_VIDEO_MODE.width, config::GAME_VIDEO_MODE.height, config::ROOM_SIZE, config::GAME_COLOR_ROOM),
+            config::GAME_VIDEO_MODE,
+            config::HARD_GAME_TITLE,
+            config::HARD_GAME_ENEMY_RATIO));
+
     m_buttons[0].set(sf::Vector2f{pos_left, pos_top}, config::BUTTON_SIZE, config::BUTTON_TEXT_EASY,
         config::BUTTON_FONT_SIZE, std::move(easy_level_command));
     m_buttons[1].set(sf::Vector2f{pos_left, pos_top + config::BUTTON_SIZE.y + pos_diff}, config::BUTTON_SIZE,
@@ -38,6 +46,8 @@ Menu::Menu(IStateManager& 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::move(hard_level_command));
     m_buttons[3].set(sf::Vector2f{pos_left, pos_top + 3*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE,
+    config::BUTTON_TEXT_EXTREME, config::BUTTON_FONT_SIZE, std::move(extreme_level_command));
+    m_buttons[4].set(sf::Vector2f{pos_left, pos_top + 4*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE,
      config::BUTTON_TEXT_EXIT, config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager));
 }
 
diff --git a/source/States/SelectState/SelectState.h b/source/States/SelectState/SelectState.h
index f94f31c3151c204b468d11b2c40426b688dd4dcb..fd99b81f2e7382a3002b2c00611f9aba469a5585 100644
--- a/source/States/SelectState/SelectState.h
+++ b/source/States/SelectState/SelectState.h
@@ -5,16 +5,16 @@
 #include <BasicAbstractions/IDrawable.h>
 #include <BasicAbstractions/Button/Button.h>
 
-class Menu: public IDrawable {
+class Menu final : public IDrawable {
 public:
     explicit Menu(IStateManager& state_manager);
     void process_mouse(sf::Vector2f pos, bool is_pressed);
     void draw_into(sf::RenderWindow& window) const override;
 private:
-    std::array<Button, 4> m_buttons;
+    std::array<Button, 5> m_buttons;
 };
 
-class SelectState : public IState, public IWindowKeeper {
+class SelectState final : public IState, public IWindowKeeper {
 public:
     explicit SelectState(IStateManager& state_manager, const sf::VideoMode& video_mode, const sf::String& window_title) :
     IState(state_manager), IWindowKeeper(video_mode, window_title), m_menu(state_manager) {