3

ベクターベースの在庫システムを機能させるのに問題があります。インベントリ内のアイテムを一覧表示することはできますが、ユーザーが選択したアイテムにアクセスすることを許可できません。コードは次のとおりです。

struct aItem
{
    string  itemName;
    int     damage;

    bool operator==(aItem other)
    {
        if (itemName == other.itemName)
            return true;
        else
            return false;
    }
};

int main()
{
    int selection = 0;


    aItem healingPotion;
    healingPotion.itemName = "Healing Potion";
    healingPotion.damage= 6;

    aItem fireballPotion;
    fireballPotion.itemName = "Potion of Fiery Balls";
    fireballPotion.damage = -2;

    aItem testPotion;
    testPotion.itemName = "I R NOT HERE";
    testPotion.damage = 9001;
    int choice = 0;
    vector<aItem> inventory;
    inventory.push_back(healingPotion);
    inventory.push_back(healingPotion);
    inventory.push_back(healingPotion);
    inventory.push_back(fireballPotion);

    cout << "This is a test game to use inventory items. Woo!" << endl;
    cout << "You're an injured fighter in a fight- real original, I know." << endl;
    cout << "1) Use an Item. 2) ...USE AN ITEM." << endl;

switch (selection)
    {
    case 1:
        cout << "Which item would you like to use?" << endl;
        int a = 1;
        for( vector<aItem>::size_type index = 0; index < inventory.size(); index++ ) 
        {

            cout << "Item " << a << ": " <<  inventory[index].itemName << endl;
            a+= 1;
        }
        cout << "MAKE YOUR CHOICE." << endl << "Choice: ";

        cin >> choice;

^^^^この線より上のすべてが機能します。私の問題はifステートメントだと思いますが、構文のどこが間違っているのか、または自分がしていることを実行するためのより良い方法があるのか​​どうかを理解できません。

        if (find(inventory.begin(), inventory.at(choice), healingPotion.itemName) != inventory.end())
            cout << "You used a healing potion!";
        else
            cout << "FIERY BALLS OF JOY!";
        break;

    case 2:
        cout << "Such a jerk, you are." << endl;
            break;

    }

編集:私はこれを正しく表現していないと思います。表示されるメッセージに影響を与えるには、プレーヤーの選択が必要です。1番目のスニペットの出力例は次のとおりです。

Item 1: Healing Potion
Item 2: Healing Potion
Item 3: Healing Potion
Item 4: Potion of Fiery Balls

MAKE YOUR CHOICE. 
Choice: 

そこから、プレーヤーは1〜4と入力できます。私が望むのは、数値(マイナス1、ゼロから始まるベクトルを反映する)を検索に渡して、(この小さな例では)次のかどうかを判断することです。 Inventory[choice-1]のアイテムは癒しのポーションです。もしそうなら、「あなたは癒しのポーションを使いました!」と表示します。そうでない場合は、「燃えるような喜びのボール」を表示します。

4

3 に答える 3

2

3つの問題。

1つは、オペレーターを次のように宣言する必要があります。

bool operator==(const aItem& other) const

2つ、このコードでは:

find(inventory.begin(), inventory.at(choice), healingPotion) != inventory.end())

begin()からへのベクトル全体を検索しているのではなく、検索セットの最後から1つを指す場所からをend()検索しているだけです。したがって、次のいずれかを行う必要があります。begin()at(choice)at(choice)

find(&inventory.at(0), &inventory.at(choice), healingPotion) != &inventory.at(choice))

またはこれ...

find(inventory.begin(), inventory.end(), healingPotion.itemName) != inventory.end())

編集3、あなたはリンゴとオレンジを比較しようとしています。一致するオブジェクトを見つけるためvectorにオブジェクトを検索していますが、送信するパラメータはオブジェクトではなく、データメンバーの1つです。aItemaItemfindaItemaItem

次のように、一致するアイテムを検索する必要があります。

find( inventory.begin(), inventory.end(), healingPotion ) != inventory.end() )
                                            ^^^^^^^^

C ++ 03では、ファンクターを提供できます。

#include <functional>
struct match_name : public std::unary_function<aItem, bool>
{
    match_name(const string& test) : test_(test) {}
    bool operator()(const aItem& rhs) const
    {
        return rhs.itemName == test_;
    }
private:
  std::string test_;
};

find_if...次に、 :を使用して一致するものを検索します。

find_if( inventory.begin(), inventory.end(), match_name(healingPotion.itemName) ) // ...

C ++ 11では、クロージャーを使用してこの混乱を単純化できます。

string test = healingPotion.itemName;
if( find_if( inventory.begin(), inventory.end(), [&test](const aItem& rhs)
{
    return test == rhs.itemName;
}) == inventory.end() )
{
  // not found
}
于 2012-11-12T19:02:21.443 に答える
0

それ以外の:

case 1:
        cout << "Which item would you like to use?" << endl;
        int a = 1;
        for( vector<aItem>::size_type index = 0; index < inventory.size(); index++ ) 
        {

            cout << "Item " << a << ": " <<  inventory[index].itemName << endl;
            a+= 1;
        }
        cout << "MAKE YOUR CHOICE." << endl << "Choice: ";

        cin >> choice;
        if (find(inventory.begin(), inventory.at(choice), healingPotion.itemName) != inventory.end())
            cout << "You used a healing potion!";
        else
            cout << "FIERY BALLS OF JOY!";
        break;

    case 2:
        cout << "Such a jerk, you are." << endl;
            break;

    }

ベクトルの驚異の1つが値に直接アクセスできることであることに気づかなかったのですが、ライアンガスリーはコメントでこれについて言及しましたが、より単純な「答え」を見つけました。すなわち:

case 1:
    cout << "Which item would you like to use?" << endl;
    //TODO: Learn what the hell the following line actually means.
    for( vector<aItem>::size_type index = 0; index < inventory.size(); index++ ) 
    {
        //Makes a numerical list.
        cout << "Item " << index + 1 << ": " <<  inventory[index].itemName << endl;
        a+= 1;
    }
    cout << "MAKE YOUR CHOICE." << endl << "Choice: ";

    cin >> choice;
    //Cannot define this outside of the statement, or it'll initialize to -1
    invVecPos = (choice - 1);

    //This checks for an invalid response. TODO: Add in non-int checks. 
    if ((invVecPos) >= inventory.size())
    {
        cout << "Choice out of bounds. Stop being a dick." << endl;
    }
    //If the choice is valid, proceed.
    else
    {
        //checking for a certain item type.
        if(inventory[invVecPos].itemType == "ITEM_HEALTHPOT")
        {
            cout << "You used a healing potion!" << endl;
            //this erases the potion, and automagically moves everything up a tick.
            inventory.erase (inventory.begin() + (invVecPos));
        }

        else if(inventory[invVecPos].itemType == "ITEM_FIREPOT")
        {
            cout << "FIERY BALLS OF JOY!" << endl;
        }

        else
        {
            //error-handling! Whee!
            cout << "Invalid Item type" << endl;
        }
    }


    break;
case 2:
    cout << "Why do you have to be so difficult? Pick 1!" << endl;
    break;

ありがとう、ライアン-あなたの提案で、私は他の場所を見て、必要なコードを見つけることができました!「修正された」コードはコメントが多いので、問題が発生した人は誰でも必要なものを収集できるはずです。

于 2012-11-14T10:40:03.123 に答える
0

John Diblingの答えに追加するために、最後の部分は、aItemではなく名前を探しているということです。

したがって、次のいずれかである必要があります。

find(inventory.begin(), inventory.end(), healingPotion) != inventory.end();

ここで、operator==は次のように定義されます。

bool operator==(const aItem& other) const
{
   return itemName == other.itemName;
}

または、operator ==に文字列を取得させる必要があります:

find(inventory.begin(), inventory.end(), healingPotion.itemName) != inventory.end();

ここで、operator==は次のように定義されます。

bool operator==(const std::string& name) const
{
   return itemName == name;
}
于 2012-11-12T19:35:26.907 に答える