1

I'm fairly new to C++ and and trying to create an epic RPG. The game has four players, each of which has an instance of class Character containing all info (name, level, hp, etc).

class character
{
public:
    string name = "Nameless";       
    int hp = 10;
    int mp = 5;
}

Somewhere else in the code I create playing characters with instances of this class:

character player1;
character player2;
character player3;
character player4;

During combat I will need to be able to change player values dynamically. I have two specific questions:

  • How can I change the HP of a randomly selected character? (string = "1"; player[string].hp = 0;)
  • How can I dynamically choose the class value to be loaded? (string = "hp"; player1.[string] = 10;)

Perhaps I should be using something else than classes for this, open to suggestions :)

Cheers!

  • 5
    Use a collection of objects instead of individual variables. `std::vector` is a reasonable choice. – molbdnilo Mar 03 '16 at 10:14
  • Seems reasonable - would you mind providing short usage examples specific to my situation? I've googled this for a bit and can't really figure it out yet – Alexander Wolff Mar 03 '16 at 10:36
  • 1
    I would recommend one of [these](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) over googling. – molbdnilo Mar 03 '16 at 10:39

2 Answers2

2

How can I change the HP of a randomly selected character? (string = "1"; player[string].hp = 0;)

Use an array instead of variables:

character players[4];

You can also add references to players if you need them:

character &player1 = players[0];
character &player2 = players[1];
character &player3 = players[2];
character &player4 = players[3];

How can I dynamically choose the class value to be loaded? (string = "hp"; player1.[string] = 10;)

Initially you can't.

Try using dictionary if you need, or overload [] operator in the class.

Anyway, it doesn't seem like a good idea.

Qwertiy
  • 19,681
  • 15
  • 61
  • 128
  • C++ doesn't have any STL class called "dictionary", so I guess you meant `std::unordered_map` ;-) – underscore_d Mar 03 '16 at 10:44
  • @underscore_d, I didn't marked the word "dictionary" as inline code. I ment any dictionary-like object. Yes it can be `map`, `unordered_map` or anything else including custom classes. – Qwertiy Mar 03 '16 at 10:47
  • Could you please provide a usage example of unordered_map in this context? After extensive googling I still quite can't figure it out – Alexander Wolff Mar 04 '16 at 07:57
  • @AlexanderWolff, I think you already have it in the other answer. – Qwertiy Mar 04 '16 at 09:27
2

How can I change the HP of a randomly selected character? (string = "1"; player[string].hp = 0;)

To easily select a random player to modify, the easiest approach is to place all players in a container such as a vector. Then you can generate a random index into the vector and modify the player at that position.

How can I dynamically choose the class value to be loaded? (string = "hp"; player1.[string] = 10;)

To dynamically choose which property you wish to modify there are a few approaches. An easy solution is shown below with a mapping from string property names to property values. Another approach is to create an enum class which enumerates the different properties and then use that as a key instead of strings.

#include <iostream>
#include <iterator>
#include <random>
#include <string>
#include <unordered_map>
#include <vector>

class character
{
    public:
        std::string name = "Nameless";
        std::unordered_map<std::string, int> properties{
            { "hp", 10 },
            { "mp", 5 }
        };
};

void print_players(const std::vector<character>& players) {
    for (const auto& player : players) {
        std::cout << player.name;
        for (const auto& property : player.properties) {
            std::cout << ", " << property.first << "=" << property.second;
        }
        std::cout << std::endl;
    }
}

int main() {
    auto players = std::vector<character>{
        character{"Player 1"},
        character{"Player 2"},
        character{"Player 3"},
        character{"Player 4"}
    };

    print_players(players);

    auto rng = std::default_random_engine{std::random_device{}()};

    // Select a random player
    auto random_player_distribution = std::uniform_int_distribution<>{0, players.size() - 1};
    auto& random_player = players[random_player_distribution(rng)];

    // Select a random property
    auto random_property_distribution = std::uniform_int_distribution<>{0, random_player.properties.size() - 1};
    auto random_property_iterator = random_player.properties.begin();
    std::advance(random_property_iterator, random_property_distribution(rng));

    // Modify random property
    random_property_iterator->second = 42;

    print_players(players);
}
user764486
  • 160
  • 5