Как создать и получить доступ к массиву объектов для мини-игры SMITE, которую я пишу - PullRequest
0 голосов
/ 16 февраля 2019

Я создаю программу, которая должна иметь массив из 100 строк.Каждая строка относится к мифологическому богу в игре SMITE.Этот бог имеет 3 важных атрибута, которые определяют, какие предметы ему разрешено использовать.

1: класс способности: воин, маг, хранитель, охотник, убийца.

2: диапазон: ближний или дальний бой.

3: Тип урона: магический или физический

По сути, эта программа получает случайного бога и строит 6 случайных элементов из разрешенного списка, к которому она может получить доступ, на основе этих атрибутов.

Эти атрибуты будут рассмотрены, чтобы определить, какие предметы разрешено использовать богу.их будет около 150, и они могут быть использованы только определенным классом, диапазоном и типом урона.

У меня есть текущее решение, которое работает, но, к сожалению, мне нужно создать целый массив строк со всеми богами, которые принадлежат к каждому типу.Например, я создаю массив из 50 магических богов, а затем массив из 20 магов.чтобы определить, какие предметы может использовать бог, я проверяю случайно сгенерированную строку бога со всеми массивами, определяющими его тип, и, если он найден, помечает этот тип.Мне интересно, возможно ли хранить этих богов как объекты со всеми этими идентификаторами.Пример.У бога «Анубис» будет класс способностей мага, тип дальнего радиуса действия и тип магического урона, хранящиеся в одном объекте, который определяет Анубиса.Таким образом, мне не пришлось бы создавать тонны длинных массивов, полных имен богов, и сравнивать их друг с другом.Если это возможно, пожалуйста, помогите.В настоящее время я нахожусь в классе программирования для C ++, и мы не рассмотрели ООП, но я немного знаком с ним из-за Python.

const int NUM_GODS = 100;
string god_list[NUM_GODS] = {"Achilles", "Agni", "Ah Muzen Cab", "Ah Puch", "Amaterasu",\
"Anhur", "Anubis", "Ao Kuang", "Aphrodite", "Apollo", "Arachne", "Ares", "Artemis",\
"Artio", "Athena", "Awilix", "Bacchus", "Bakasura", "Baron Samedi",\
"Bastet", "Bellona", "Cabraken", "Camazotz", "Cerberus", "Cernunnos",\
"Chaac", "Chang'e", "Chernobog", "Chiron", "Chronos", "Cu Chulainn",\
"Cupid", "Da Ji", "Discordia", "Erlang Shen"}; //There are many many more but this is just a sample for an idea

1 Ответ

0 голосов
/ 17 февраля 2019

Имея в виду ваши текущие цели, я структурировал бы ваш код примерно так:

#include <string>
#include <sstream> // needed for stringstream
#include <vector>
#include <iostream>
#include <fstream>
#include <exception>

enum class AbilityType {
    WARRIOR,
    MAGE,
    GUARDIAN,
    HUNTER,
    ASSASSIN,
    HEALER
};

enum class AttackType {
    MELEE,
    RANGE
};

enum class DamageType {
    MAGICAL,
    PHYSICAL
};

struct EntityAttributes {
    AbilityType abilityType;
    AttackType attackType;
    DamageType damageType;
};

class Entity {
private:
    std::string name_;
    EntityAttributes attribs_;

public:
    Entity() = default;
    explicit Entity(const std::string& name) : 
        name_(name) 
    {}
    Entity(const std::string& name, EntityAttributes attribs) :
        name_(name),
        attribs_(attribs)
    {}

    void assignAttributes(EntityAttributes attribs) {
        attribs_ = attribs;
    }

    std::string getName() const { return name_; }

    AbilityType getAbilityType() const { return attribs_.abilityType; }
    AttackType getAttackType() const { return attribs_.attackType; }
    DamageType getDamageType() const { return attribs_.damageType; }
};

void getAllLinesFromFile(const char* filename, std::vector<std::string>& output) {
    std::ifstream file(filename);
    if (!file) {
        std::stringstream stream;
        stream << "failed to open file " << filename << '\n';
        throw std::runtime_error(stream.str());
    }

    std::string line;
    while (std::getline(file, line)) {
        if (line.size() > 0)
            output.push_back(line);
    }
    file.close();
}

int main() {
    try {
        // This will store all of the names in from our text file.
        std::vector<std::string> names;
        getAllLinesFromFile("Names.txt", names);

        // This will give us a container of all of our entities with a provided name
        // after this container is filled you can go back later and add the addition
        // properties, or if you read the properties in from a file as well you can use
        // the other Entity constructor to generate all of them with their names and properties
        std::vector<Entity> entities;
        for (auto& n : names) {
            Entity e(n);
            entities.push_back(e);
        }

        // Check our array of Entities
        std::cout << "There are " << entities.size() << " entities\n";
        for (auto& e : entities) {
            std::cout << e.getName() << '\n';
        }

    } catch( std::runtime_error& e ) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;    
}

В приведенном выше примере основной текстовый файл "Names.txt" содержит имя объекта наодна строка.Я прочитал файл, извлекая построчно, потому что если бы мы сделали только один cin >> string, он получал бы только первый набор символов, пока не встретил пробел.Таким образом, текстовый файл с именами сущностей выглядит следующим образом:

-Names.txt-

Achilles
Agni
Ah Muzen Cab
Ah Puch
Amaterasu
Anhur
Anubis
Ao Kuang
Aphrodite
Apollo
Arachne
Ares
Artemis
Artio
Athena
Awilix
Bacchus
Bakasura
Baron Samedi
Bastet
Bellona
Cabraken
Camazotz
Cerberus
Cernunnos
Chaac
Chang'e
Chernobog
Chiron
Chronos
Cu Chulainn
Cupid
Da Ji
Discordia
Erlang Shen

Это довольно просто и просто сделать.Теперь, если вы хотите добавить в этот текстовый файл различные атрибуты, которые каждая из этих сущностей способна использовать, вы, безусловно, можете это сделать, однако это сделает анализ файла немного сложнее.Если бы это было так, то символы с именами, состоящими из более чем одного слова, должны быть заключены в какой-то специальный символ, такой как кавычки " ".Я приведу простой пример того, как может выглядеть текстовый файл;однако метод чтения в тексте может быть похожим, но метод синтаксического анализа строк в сохраненном векторе будет другим.

Achilles Warrior Melee Physical   // easy enough only single words to extract from the vector
"Baron Samedi" Mage Range Magical // Here when we parse this line, Baron Samedi is in quotes so that would be our "name" variable then the rest would follow as before.

Перечисляемые типы здесь являются перечислителями с областью видимости из-за class объявив таким образом, вы не можете обмениваться значениями следующим образом:

AttackType attType = PHYSICAL; // This will fail to compile.
AttackType attType = DamageType::PHYSICAL; // will still fail to compile.

, поскольку они будут генерировать необходимые для вас ошибки компилятора.

Кроме того, используя векторы выше для хранения вашего типа класса, выне нужно явно указывать определенное количество объектов, и это значение не нужно знать во время компиляции.С этой версией кода вам не нужно использовать необработанные массивы и вам не нужно беспокоиться о выходе за пределы при индексации в массив.Здесь std::vector делает все это за вас!


Это просто то, о чем нужно подумать в вашей общей структуре дизайна.Это облегчает управление ресурсами, код легче читать и отлаживать.Он многоразовый и должен быть достаточно портативным.Вы всегда можете изменить текстовый файл, чтобы внести изменения в список символов и их атрибутов без необходимости перестраивать или перекомпилировать свой код. Все, что вам нужно сделать, это изменить ваш текстовый файл и снова запустить программу.Это также помогает уменьшить время компиляции и сборки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...