0

I'm fairly new to coding in c++, and I'm working on a menu system for a text RPG I'm working on. You can view your stats, view your inventory, view item stats, and discard items. However, after the item is discarded, which ever slot the discarded item was in remains empty, and in a game it doesn't make sense to have object 2 be discarded, and then what was object number 3 remain object 3. Object 3 should become 2. So I was wondering how I could do this with my current code.

#include <iostream>
#include <string>
using namespace std;

bool running = 1;

void titleFunc();
void newGameFunc();
void menuFuncNav();
void menuFuncInfo();
void menuFuncItems();
string itemNames[] = {"Iron Short Sword", "Iron Long Sword", "Iron Two-Handed Sword", "Iron War Hammer", "Iron Mace", "Iron Dagger", "Wooden Staff", "Wooden Shield", "Oak Shortbow", "Oak Longbow", "Oak Crossbow", "Hard Leather Chest-Piece", "Hard Leather Leggings", "Soft Leather Chest-Piece", "Soft Leather Leggings", "Cloak"};
short playerItemCount = 0;
int userInput = 0;
int talkInput = 0;
int playerInfo[3];
int playerLocation = 0;
const int MAX_ITEMS = 100;
int playerItems[MAX_ITEMS][11];




void menuFuncItems()
{
    int i = 0;
    for( int i = 0; i < playerItemCount; i++ )
    {
        cout << i+1 << ": "; 
        cout << itemNames[playerItems[i][0]]; 
        cout << endl;
    }
    cin >> i;
    if( playerItems[i - 1][1] == 1 )
    {
        cout << "Press 1 to view stats." << endl;
        cout << "Press 2 to equip." << endl;
        cout << "Press 3 to discard." << endl;
        cin >> userInput;
        cout << endl;

        if( userInput == 1 )
        {
            cout << "Name: " << itemNames[playerItems[i - 1][0]] << endl;
            cout << "Physical Attack:" << playerItems[i - 1][2] << endl;
        }
        else if( userInput == 2 )
        {

        }
        else
        {   
            playerItems[i - 1][0]--;
            playerItems[i - 1][0]--;



            cout << "Item discarded." << endl;
        }
    }

So in this code, the player discards the item in the first inventory slot.

  1. Iron Longsword
  2. Wooden shield
  3. Hard Leather Chest-Piece
  4. Hard Leather Leggings

Should become, after item 1 is discarded:

  1. Wooden Shield
  2. Hard Leather Chest-Piece
  3. Hard Leather Leggings

Sorry if I did something wrong in the post. This is my first post on this site. :) Thank you.

Haseo
  • 1
  • 4
    You might find [this question and answers](http://stackoverflow.com/questions/347441/erasing-elements-from-a-vector/347478#347478) helpful, particularly if you use a `std::vector<>` as you should rather than a fixed array. – WhozCraig Oct 29 '13 at 21:16
  • 1
    If the ordering of items isn't important, you could just copy the last item in the array over the slot of the just-removed-item, then decrement your array-length variable. OTOH if you want to retain ordering, you'll have to do a for loop such that every item after the removed-index gets copied over to the previous index. – Jeremy Friesner Oct 29 '13 at 21:19
  • The thing with arrays is that that's exactly how they should behave. Like @WhozCraig says, you should be using a different data structure that stores data exactly the way you want. – nonsensickle Oct 29 '13 at 21:25
  • Expanding Jeremy's first comment (+1 btw), your second list would become "1. Hard Leather Leggings 2. Wooden shield 3. Hard Leather Chest-Piece". I hope that was obvious, but in case it wasn't. – WhozCraig Oct 29 '13 at 21:26
  • So, what you're saying nonsensical, is that the simplest way to do this would be to use a different data structure? Will the different data structure do what I want on it's own, or will I still need to tell it to do it somehow? – Haseo Oct 29 '13 at 21:31

2 Answers2

0

For example you can do the following

for ( int ( *p )[11] = playerItems + i; p != playerItems + playerItemCount; ++p )
{
    std::copy( *p, *p + 11, *( p - 1 ) );
}
--playerItemCount;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

If you replace

int playerItems[MAX_ITEMS][11];

with

std::vector<int> playerItems; // assuming you store all the items for a given player here

or

std::vector<std::vector<int>> playerItems;  // if you want the 2D array for whatever implementation you have

Then erasing an element is as simple as calling playerItems.erase(it); (where it is an iterator "pointing" to the element you want to remove.

Alternatively, if you want a faster insertion/removal (but slower random access), you can use std::list. If you really want to have fun, you can store them in a std::map with the name of the item as the key (instead of using an index to make to the item name string in another array).

Zac Howland
  • 15,777
  • 1
  • 26
  • 42