13 Replies - 2772 Views - Last Post: 04 November 2013 - 09:29 PM Rate Topic: -----

#1 KruSuPhy  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 30-June 10

[C++]text-based RPG Inventory system

Posted 22 October 2013 - 08:51 PM

Hello, I'm fairly new to C++, and I've been working on a text-based RPG for a couple weeks now for about an hour a day(it's all the time I've got, I do it at night when I get home) as a learning experience. All in all, it's been a really fun way to learn, and I've learned a decent amount already. However, as of the past couple days, I've been working on implementing an Inventory/Item system. I've hit a wall. I really have no idea how to do it.

I've thought of using an Inventory class and an Item class, using the Inventory class to call on an Item class array(is that even possible?), but decided that'd probably just be too complicated. I've also tried to use a struct Item, and then work with an Inventory class, but I also have no idea how I'd do that.

I guess the problem is that I don't know how I'd identify the item later on. I feel like I could probably create the items easily enough using the struct(if that's even a good idea), and making the array should be simple enough, i suppose. But how would I go about adding the item to the inventory and being able to identify what it is?

I hate to sound really confusing, but I think I'm just completely not getting it. So, if anyone could help me be less-confused by any amount, I'd really appreciate it!

Thanks

Is This A Good Question/Topic? 0
  • +

Replies To: [C++]text-based RPG Inventory system

#2 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3529
  • View blog
  • Posts: 10,931
  • Joined: 05-May 12

Re: [C++]text-based RPG Inventory system

Posted 22 October 2013 - 08:56 PM

The key questions you need to ask yourself is what does the Inventory class do? What does the Item class do? If the inventory class doesn't do much, you may be able to get by with a simple vector of Item's.
Was This Post Helpful? 0
  • +
  • -

#3 KruSuPhy  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 30-June 10

Re: [C++]text-based RPG Inventory system

Posted 23 October 2013 - 10:09 AM

Well, the Item class/struct will just basically define the items, such as std::string name, int itemID, int price, ITEM_TYPE itemType, using a public enum ITEM_TYPE to define the different types of items, which is why I'm thinking it should just be a struct as opposed to the class. Now, the Inventory class would manage the items in the inventory, AddItem, UseItem, etc. But I guess I could probably include all of that in my Character or Game class, right?
Was This Post Helpful? 0
  • +
  • -

#4 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5795
  • View blog
  • Posts: 12,627
  • Joined: 16-October 07

Re: [C++]text-based RPG Inventory system

Posted 23 October 2013 - 11:00 AM

A struct and a class are the same in C++; just the default access is different. But, if you're thinking you can get away with just a simple collection of data for your item, then that should be your first attempt.

There are some items that might be different, though. e.g.
struct Item {
   int itemId;
   std::string name;
   int price;
   int type;
};

// a weapon?
struct Weapon : public Item {
   int attack;
   int damage;
};

// armour?
struct Armour : public Item {
   int defense;
};

// your collection...
typedef std::vector<Item *> Items;


Was This Post Helpful? 0
  • +
  • -

#5 KruSuPhy  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 30-June 10

Re: [C++]text-based RPG Inventory system

Posted 24 October 2013 - 09:23 AM

Sorry, I've tried for a while now to understand vectors, and I think I sorta get them, but I'm not sure how to use it with typedef.
If I understand correctly, then I'd just initialize the vector with std::vector<Item> Items; and then use Items.push_back();, right? But, in using typedef, would I do the same thing, or would I have to do something like;
Items inventory;
inventory.push_back(sword);


or what?
Was This Post Helpful? 0
  • +
  • -

#6 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5795
  • View blog
  • Posts: 12,627
  • Joined: 16-October 07

Re: [C++]text-based RPG Inventory system

Posted 24 October 2013 - 10:29 AM

Pretty much. However... C++ is not all that friendly when it comes to polymorphism. To make everything play nice with a class hierarchy, you're kind of stuck using pointers.

A quick and dirty example:
#include <iostream>
#include <vector>

// base class
struct Item {
   const int itemId;
   const char *name;
   Item(int i, const char *n) : itemId(i), name(n) { }
   virtual const char *typeName() const { return "Item"; }
   virtual void print(std::ostream &out) const { 
	   out << typeName() << " (" << itemId << ") " << name;
   }
};

typedef std::vector<Item *> Items;


// armour?
struct Armour : public Item {
   const int defense;
   Armour(int itemId, const char *name, int d) : Item(itemId, name), defense(d) { }
   virtual const char *typeName() const { return "Armour"; }
   virtual void print(std::ostream &out) const { 
	   Item::print(out);
	   out << ": AC(" << defense << ')';
   }
};

std::ostream &operator<<(std::ostream &, const Item &);
std::ostream &operator<<(std::ostream &, const Items &);


int main() {
	Items items;
	items.push_back(new Item(1, "Widget"));
	items.push_back(new Item(2, "Anvil"));
	items.push_back(new Armour(200, "Halberk", 5));
	items.push_back(new Armour(208, "Flack Jacket", 7));
	std::cout << items << std::endl;
	return 0;
}


using namespace std;

std::ostream &operator<<(std::ostream &out, const Item &item) {
	item.print(out);
	return out;
}

std::ostream &operator<<(std::ostream &out, const Items &items) {
	for(Items::const_iterator it = items.begin(); it != items.end(); ++it) {
		out << **it << std::endl;
	}
	return out;
}


Was This Post Helpful? 0
  • +
  • -

#7 KruSuPhy  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 30-June 10

Re: [C++]text-based RPG Inventory system

Posted 26 October 2013 - 01:23 AM

I'm really sorry, so please excuse my ignorance, but what is the difference between <Item> and <Item *>?
I've tried to study on pointers several times, but I still don't understand the advantage of using them. I understand that Item * would be "value pointed by Item", and & would be "address pointed to by Item", but I just don't understand the advantage of using Item * as opposed to using Item.

I'm not trying to sound like a helpless newbie at all, though I probably do, but I just don't get pointers. I've even used Learning C++ Pointers for REAL Dummies, and I just don't get the advantage.
I get that using
int a;
int b;
int c;
int a = 5;
int b = &a;
int c = *b;
cout << c;


would output 5, but I just don't get the purpose of that as opposed to using a = 5, c = a;, cout << c;?
and sorry, but I'm not quite in my right mind now, so this might not make much sense, but I'll edit it tomorrow if it seems too confusing.
And that's not the only thing that seems weird to me. I apologize, but I programmed in VB6 for about 6 years, and this is all confusing to me. Again, I apologize for my question if it seems kinda weird as of the moment.
Was This Post Helpful? 0
  • +
  • -

#8 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5795
  • View blog
  • Posts: 12,627
  • Joined: 16-October 07

Re: [C++]text-based RPG Inventory system

Posted 26 October 2013 - 03:04 AM

View PostKruSuPhy, on 26 October 2013 - 04:23 AM, said:

I programmed in VB6 for about 6 years


Scarred for life. Understood. ;)

In a perfect C++ world, you would avoid pointers entirely. However, it turns out, they're almost unavoidable. In C, the foundational language that brought you pointers, they're invaluable. In C++, they are the strange child that's kept in the basement, that everyone tries to ignore, until it occasionally gets out and kills a house pet.

All variables are simply a labels for memory locations. A pointer is a variable that stores a value, like any other, but the value happens to be a memory address. There is then syntax built around that so you can use the value of the memory address to reference the value AT the memory address stored and not that memory address value itself.

A pointer lets you translate a memory location into a variable of a certain type. Consider:
int n = 42;

cout << "n = " << n << " sizeof(n) = " << sizeof(n) << endl;

unsigned char *pc = (unsigned char *)&n;
for(int i=0; i<sizeof(n); i++) {
	cout << "pc[" << i << "] = " << (int)pc[i] <<  endl;
}
pc[1] = 1;
cout << "n = " << n << endl;

unsigned char &c = *((unsigned char *)&n);
cout << "c = " << (int)c << endl;
c++;
cout << "c = " << (int)c << endl;
cout << "n = " << n << endl;



Results:
n = 42 sizeof(n) = 4
pc[0] = 42
pc[1] = 0
pc[2] = 0
pc[3] = 0
n = 298
c = 42
c = 43
n = 299



And this, is, kind of why we need pointers for polymorphism. I could say that c is a base type and n is a sub type, but n takes a lot more storage. A pointer just holds a memory location and lets that storage exist without the rest of my program needing to worry about the size.

So, polymorphism.
#include <iostream>

using namespace std;

struct Point { 
	int x, y; 
	Point(int _x=0, int _y=0) : x(_x), y(_y) { } 
};

struct Point3D : public Point { 
	int z;
	Point3D(int _x=0, int _y=0, int _z = 0) : Point(_x,_y), z(_z) { } 
};

void show(const Point &p) { cout << "Point(" << p.x << ',' << p.y << ')'; }

void show(const Point3D &p) { 
	cout << "Point3D(" << p.x << ',' << p.y << ',' << p.z << ')';
}

int main() {
	const int SIZE = 2;
	Point *points[SIZE] = { new Point(1,2), new Point3D(4,5,6) };
	
	for(int i=0; i<SIZE; i++) {
		cout << i << ' '; show(*points[i]); cout <<  endl;
	}
	
	Point *p1 = points[1];
	Point3D *p2 = (Point3D *)p1;
	cout << "p1 "; show(*p1); cout <<  endl;
	cout << "p2 "; show(*p2); cout <<  endl;
	
	
	return 0;
}



Results:
0 Point(1,2)
1 Point(4,5)
p1 Point(4,5)
p2 Point3D(4,5,6)



You see, an array of Point not only couldn't hold a Point3D due to type, it simply wouldn't have the storage for it. However, an array of Point pointers allows all objects to be considered Point. We happen to know one is more than just Point and we can manipulate it accordingly.

Hope this helps. I'm sure it's still confusing. Read as much as you can. You'll get it eventually. You can find others, I'm sure, who explain this far better than I.
Was This Post Helpful? 2
  • +
  • -

#9 KruSuPhy  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 30-June 10

Re: [C++]text-based RPG Inventory system

Posted 30 October 2013 - 07:57 PM

View Postbaavgai, on 24 October 2013 - 10:29 AM, said:

Pretty much. However... C++ is not all that friendly when it comes to polymorphism. To make everything play nice with a class hierarchy, you're kind of stuck using pointers.

A quick and dirty example:
#include <iostream>
#include <vector>

// base class
struct Item {
   const int itemId;
   const char *name;
   Item(int i, const char *n) : itemId(i), name(n) { }
   virtual const char *typeName() const { return "Item"; }
   virtual void print(std::ostream &out) const { 
	   out << typeName() << " (" << itemId << ") " << name;
   }
};

typedef std::vector<Item *> Items;


// armour?
struct Armour : public Item {
   const int defense;
   Armour(int itemId, const char *name, int d) : Item(itemId, name), defense(d) { }
   virtual const char *typeName() const { return "Armour"; }
   virtual void print(std::ostream &out) const { 
	   Item::print(out);
	   out << ": AC(" << defense << ')';
   }
};

std::ostream &operator<<(std::ostream &, const Item &);
std::ostream &operator<<(std::ostream &, const Items &);


int main() {
	Items items;
	items.push_back(new Item(1, "Widget"));
	items.push_back(new Item(2, "Anvil"));
	items.push_back(new Armour(200, "Halberk", 5));
	items.push_back(new Armour(208, "Flack Jacket", 7));
	std::cout << items << std::endl;
	return 0;
}


using namespace std;

std::ostream &operator<<(std::ostream &out, const Item &item) {
	item.print(out);
	return out;
}

std::ostream &operator<<(std::ostream &out, const Items &items) {
	for(Items::const_iterator it = items.begin(); it != items.end(); ++it) {
		out << **it << std::endl;
	}
	return out;
}


I've been playing around with this code for a little bit now, and I believe I understand most of it now, except for the overloading of the << operator. I've googled it a little bit and it hasn't really helped. I don't really get what it does.
Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3529
  • View blog
  • Posts: 10,931
  • Joined: 05-May 12

Re: [C++]text-based RPG Inventory system

Posted 30 October 2013 - 10:32 PM

Is it the operator overloading itself that is confusing you, or what it does inside the function?
Was This Post Helpful? 0
  • +
  • -

#11 KruSuPhy  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 30-June 10

Re: [C++]text-based RPG Inventory system

Posted 03 November 2013 - 12:01 PM

I believe it's the overloading itself that I don't quite understand. I mean, I assume it's changing the << operator to do something else, but I'm not sure how, or why, or what it's actually doing.
Was This Post Helpful? 0
  • +
  • -

#12 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5795
  • View blog
  • Posts: 12,627
  • Joined: 16-October 07

Re: [C++]text-based RPG Inventory system

Posted 03 November 2013 - 01:21 PM

It's really just a way to make << a consistent output operator for all types.

When you say ostream &operator << (ostream &out, X);, you are defining the rule for ostream << X. Now, cout is a child of ostream. Also, understand that operators kind of collapse on evaluation.

e.g.
cout << x << y;
evaluates as
cout << x returns cout
then 
cout << y returns cout
then, returned cout is ignored



Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#13 KruSuPhy  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 30-June 10

Re: [C++]text-based RPG Inventory system

Posted 04 November 2013 - 09:17 PM

So, for the two lines:

std::ostream &operator<<(std::ostream &out, const Item &item)
std::ostream &operator<<(std::ostream &out, const Items &items)

This means that the first one will only execute in a situation where the code is something like
cout << Item;
, and the second one will only execute for something like
cout << Items;
, right?
Was This Post Helpful? 0
  • +
  • -

#14 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3529
  • View blog
  • Posts: 10,931
  • Joined: 05-May 12

Re: [C++]text-based RPG Inventory system

Posted 04 November 2013 - 09:29 PM

Yes. The compiler will try to match up the parameters.

It's just like when you have:
void Foo(double d)
{
    cout << "I have a double";
}

void Foo(int n)
{
    cout << "I have an integer";
}

:

Foo(1.75);    // calls Foo(double d)
Foo(9);       // calls Foo(int n)


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1