Okay so I have an inventory class that accesses a static vector from my base class MainShop. I also have a SwordShop class which inherits from MainShop. (Both Inventory and SwordShop are derived classes).

//SwordShop class
void SwordShop::Shop
{
//I have a setter function where it takes an integer and a string and adds its to my hashmap.
//Also have a getter function which has a for loop displaying my items in my map
this->setWeaponSoldier(1, "1) Meito Ichimonji\n   +4 Damage\n   150Gold");
this->setWeaponSoldier(2, "2) Shusui\n   +10 Damage\n   230Gold");
this->setWeaponSoldier(3, "3) Elixir\n   +16 Damage\n   300Gold");
this->setWeaponSoldier(4, "4) Blade of scars\n   +24 Damage\n   550Gold");
this->setWeaponSoldier(5, "5) Ragnarok\n   +32 Damage\n   610Gold");
this->setWeaponSoldier(6, "6) Eternal Darkness\n   +40 Damage\n   690Gold");
this->setWeaponSoldier(7, "7) Masamune\n   +52 Damage\n   750Gold");
this->setWeaponSoldier(8, "8) Soul Calibur\n   +60 Damage\n   900Gold");

}

//Function in my inventory class
void Inventory::DisplayInventory()
{
    int choice;
    cout << "\nWhat do you want to do?\n1) Check Status\n2) Equip Weapons\n";//Equip what is in your inventory
    cin >> choice;
    switch (choice)
    {
        case 1: this->DisplayStats();
            break;
        case 2:cout << WeaponInventory.size() << endl;//debug
            if (!WeaponInventory.empty())//Make sure inventory is not empty
            {
                cout << "Your current Weapons are: \n";
                for (unsigned int i = 0; i < WeaponInventory.size(); ++i)
                    cout << i+1 << ") " << WeaponInventory[i] << endl;//cout whats currently in my inventory
                cout << "What item weapon would you like to equip?";
                /***********Here is the problem*******************/
                //how can I make the user choose the actual and correct item in the inventory?
                //cin >> equipChoice;
                //code goes here
            }
            else cout << "Error! You currently do not own any items\n";
            break;
  }

So for example lets say the user adds Meito Ichimonji into my WeaponInventory vector and then adds another one. How can I make the user have the ability to pick the right item? Im looking for something like this:

//PseudoCode
Displays my inventory with for loop
I have two items in it which user buys
1)Meito Ichimonji
and 
2)Elixir
cout << "what would you like to equip?";
cin >> equipChoice
if (equipChoice == 1)//chooses whatever item is first
check to see what the attack that the weapon has and add it to my attack
attack += 20;//lets say the sword had 20 attack
else if (equipChoice == 2)//chooses whatever is second
do something else
etc...

Sorry if I have not explained it clearly, but I tried my best!

How are the weapons stored? Are they always a string in display format? Because it would be easier to have a weapon class that separates these things and makes it easier to work with:

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <vector>

using namespace std;

struct Weapon {
    string _name;
    int _damage;
    int _value;

    Weapon()
        : _name(""), _damage(0), _value(-1)
    {}

    Weapon(const string& name, int damage, int value)
        : _name(name), _damage(damage), _value(value)
    {}
};

map<string, Weapon> supported_weapons = {
    {"Fist", Weapon("Fist", 1, -1)},
    {"Masamune", Weapon("Masamune", 52, 750)}
};

class Adventurer {
    vector<Weapon> _weapon_inventory;
    Weapon _equipped_weapon;
    int _base_damage;
public:
    Adventurer(int base_damage = 1)
        : _base_damage(base_damage)
    {
        _weapon_inventory.push_back(supported_weapons["Fist"]);
        equip("Fist");
    }

    void add_weapon(Weapon weapon)
    {
        _weapon_inventory.push_back(weapon);
    }

    Weapon equipped_weapon() const
    {
        return _equipped_weapon;
    }

    bool equip(const string& name)
    {
        auto match = find_if(
            _weapon_inventory.begin(), 
            _weapon_inventory.end(), 
            [&name](const Weapon& weapon) { return weapon._name == name; });

        if (match != _weapon_inventory.end()) {
            _equipped_weapon = *match;
            return true;
        }
        else {
            return false; // Weapon not available
        }
    }

    int roll_damage() const
    {
        return 1 + rand() % (_base_damage + _equipped_weapon._damage);
    }
};

In your code you might do something like this:

cout << "Choose a weapon to equip: ";

if (getline(cin, name) && equip(name)) {
    cout << name << " equipped\n";
}
else {
    cout << "Could not equip selected weapon\n";
}

OMG AMAZING!!! There is so many things here that I never learned, but are very interesting! I will defenitely look them up so I can understand the code better. Thank you for leading me in the right direction :D

By the way, is there a specific reason you used a struct for the weapon but a class for the adventurer?

is there a specific reason you used a struct for the weapon but a class for the adventurer?

If it were a class, Weapon would need getters and setters for each data member. At that point I didn't see any need, so just made them public by default as a structure. Adventurer on the other hand has other stuff going on (including stuff that I didn't include for brevity), so it makes more sense to lock down the data members.

Edited 2 Years Ago by deceptikon

Hey deceptikon, can you explain to me how the find_if works? How is it better than the normal find algorithm? I looked it up, but I still dont understand it quite well :(

Edited 2 Years Ago by Damian_2

can you explain to me how the find_if works?

It works exactly like find, except instead of comparing against a value, it calls a predicate (in the form of a function, function object, or lambda). This gives you more flexibility in customizing exactly how you want the values in the vector to be compared.

I still dont understand it quite well

Will a definition help? find_if works like this:

template <typename InputIter, typename Pred>
InputIter find_if(InputIter first, InputIter last, Pred compare)
{
    while (first != last)
    {
        if (compare(first))
        {
            break;
        }

        ++first;
    }

    return first;
}

OHHH!! i Undertstand it now! thank you so much! I was lost in your code because of the "[&name]", but I guess that's a lambda like you said. So basically what this code:

auto match = find_if(
            _weapon_inventory.begin(), 
            _weapon_inventory.end(), 
            [&name](const Weapon& weapon) { return weapon._name == name; });

does is that it looks through my vector and returns a boolean value if the weapon._name is equal to what you entered into the parameter?

But then,

if (match != _weapon_inventory.end()) {
            _equipped_weapon = *match;
            return true;

makes no sense to me. I thought match was what was returned from the find_if algorithm, but then you compare it to my vector and you even do this: _equipped_weapon = *match;. I'm sorry if im bothering you by asking all of these questions, but I want to make sure I truly understand it. Thank you :D

The reason im trying so hard to understand this logic is because I want to be able to figure out how to know when I have already equipped something. For example, if i run my code I will get:

Your current Weapons are:
1) Meito Ichimonji
2) Shusui
What item weapon would you like to equip?
(if i choose 1)
run your equip algorithm here...
it will say:
You have Successfully equipped Meito Ichimonj

But lets say I accidentally click to re-quip the same weapon, it will say "you have succesfully equipped Meito Ichimonji" again, but I want it to say "Sorry, you already have that weapon equipped." But for that I was thinking maybe I needed another find_if() inside the first find_if() to catch that exception.

Edited 2 Years Ago by Damian_2: grammatical errors

This question has already been answered. Start a new discussion instead.