Для поддержки считывания клавишь нужен сurses.h
sudo apt-get install libncurses5-dev libncursesw5-dev
g++ main.cpp -o main -lncurses -DNCURSES_STATIC
Основная идея:
Игрок управляет персонажем, который перемещается между локациями (комнатами, областями), может подбирать и использовать предметы, взаимодействовать с другими существами (дружественными или враждебными) и выполнять простые квесты или достичь определенной цели (например, найти выход, победить босса). Взаимодействие происходит через текстовые команды (например, "идти север", "взять ключ", "атаковать гоблина", "поговорить с торговцем").
Как концепции из модулей ложатся в проект:
-
Модуль 2: Управление Ресурсами (Умные Указатели)
- std::unique_ptr: Идеально подходит для управления уникально владеемыми объектами: Предметы в инвентаре игрока (каждый предмет принадлежит только игроку). Монстры или NPC, которые находятся в конкретной локации и "принадлежат" ей до их уничтожения или ухода. Возможно, сама локация, если они создаются динамически.
- std::shared_ptr: Может понадобиться, если объекты могут иметь разделяемое владение: Предметы, которые могут лежать в локации и быть одновременно "целью" для нескольких NPC или игрока. Квестовые предметы, на которые могут ссылаться разные части игры (например, квестовый лог и сама локация). (Для начала можно стараться обходиться unique_ptr для простоты, но shared_ptr — мощный инструмент).
- RAII: Весь принцип управления объектами через умные указатели — это RAII в действии. Память под монстров, предметы и т.д. будет освобождаться автоматически.
-
Модуль 3: Возможности C++17
- : Сохранение и загрузка состояния игры (прогресс игрока, состояние локаций, инвентарь) в файлы или директории. Проверка наличия файлов сохранений.
- std::optional: Возврат результата действия: функция tryMove("север") может возвращать std::optional<Location*> (указатель на новую локацию, если переход возможен, иначе std::nullopt). Поиск предмета в локации или инвентаре: функция findItem("ключ") может возвращать std::optional<Item*> или std::optional<std::unique_ptr&>. Представление необязательных данных у объектов (например, std::optional у NPC).
- std::variant: Представление разных типов предметов в одном контейнере, если не используется наследование (хотя с ООП наследование может быть лучше). Представление различных типов эффектов от зелий или заклинаний (std::variant<HealEffect, DamageEffect, BuffEffect>). Представление различных результатов действия (std::variant<SuccessMessage, ErrorMessage, CombatResult>).
- std::string_view: Эффективная передача текстовых команд, описаний локаций/предметов в функции без лишнего копирования std::string.
- Структурные привязки: Удобная распаковка пар или кортежей при работе с результатами функций или при итерации по std::map (например, выходы из локации std::map<std::string, Location*>).
- if constexpr: Может пригодиться в шаблонном коде (см. Модуль 4), если обработка зависит от типа во время компиляции.
-
Модуль 4: Шаблоны
- Шаблоны функций: Создание обобщенных утилит, например: template findEntityByName(const std::vector<std::unique_ptr>& entities, const std::string& name) для поиска игрока, монстра или предмета по имени. Шаблонная функция для загрузки разных типов данных (локации, предметы, монстры) из файлов схожего формата.
- Шаблоны классов: Возможно, обобщенный класс Inventory для хранения разных типов предметов (хотя полиморфизм через базовый класс Item может быть предпочтительнее). Шаблонный компонент для системы характеристик (Stats<Strength, Dexterity, ...>).
-
Модуль 5: ООП (Наследование и Полиморфизм)
- Иерархия классов: Базовый класс Entity (Сущность) с общими свойствами (имя, описание). От него наследуются Player, Monster, NPC. Базовый класс Item (Предмет) с общими свойствами (имя, описание, вес). От него наследуются Weapon, Armor, Potion, Key. Класс Location (Локация) с описанием, списком выходов, списком предметов и существ в ней.
- Виртуальные функции (virtual): Ключевой элемент для полиморфизма. virtual void Entity::update() { ... } (обновление состояния существа каждый ход). virtual void Entity::attack(Entity& target) { ... } (разные существа атакуют по-разному). virtual void Item::use(Entity& user) { ... } (разные предметы используются по-разному: зелье выпивается, ключ используется на двери, оружие экипируется). virtual std::string Item::getDescription() const { ... } (получение описания).
- Абстрактные классы: Базовые классы Entity и Item могут быть абстрактными, если у них нет смысла существовать самостоятельно, а только как родитель для конкретных типов.
Основные Компоненты Проекта:
- Game / GameManager: Основной класс, управляющий игровым циклом, состоянием игры, связывающий все компоненты.
- Parser: Модуль, отвечающий за разбор команд игрока (например, разделение "взять серебряный ключ" на команду "взять" и объект "серебряный ключ").
- Player: Класс, представляющий игрока (наследуется от Entity), хранит инвентарь, характеристики, текущую локацию.
- Location: Класс для локаций, хранит описание, выходы (например, std::map<std::string, Location*>), существ (std::vector<std::unique_ptr>) и предметы (std::vector<std::unique_ptr>).
- Entity Hierarchy: Entity, Monster, NPC.
- Item Hierarchy: Item, Weapon, Armor, Potion, Key и т.д.
- SaveLoad System: Модуль для сохранения/загрузки игры с использованием .
Рекомендации для Портфолио:
- Чистый код: Используйте осмысленные имена переменных и функций, следуйте единому стилю форматирования (например, ClangFormat).
- Комментарии: Добавляйте комментарии там, где код не очевиден, или для объяснения архитектурных решений (Javadoc-стиль для документирования классов и методов).
- Система сборки: Используйте CMake для управления сборкой проекта. Это стандарт индустрии.
- Версионирование: Обязательно используйте Git с самого начала проекта. Делайте осмысленные коммиты. Разместите проект на GitHub/GitLab.
- README.md: Напишите хороший README-файл с описанием проекта, инструкциями по сборке и запуску, а также кратким обзором использованных технологий и концепций C++.
- (Опционально) Тесты: Написание юнит-тестов (с использованием фреймворков вроде Google Test) для ключевых компонентов значительно повысит ценность проекта в глазах работодателя.
Начало работы:
-
Не пытайтесь реализовать все сразу! Начните с малого:
- Базовые классы: Location, Entity, Player.
- Перемещение между 2-3 статично созданными локациями.
- Добавление Item и инвентаря игрока (std::vector<std::unique_ptr>).
- Команды "взять"/"бросить".
- Постепенно добавляйте монстров, бой, сохранение/загрузку и другие фичи.
Этот проект даст вам обширную практику во всех запрошенных областях и станет отличным дополнением к вашему резюме. Удачи! Если решите взяться, спрашивайте на любом этапе!