Printing a vector in the main function using get and set Functions

So I'm trying to program a game for my C++ class, dealing with subclasses and polymorphism. This is using Object Oriented Programming of course.

Here is the code for the inventory in the .h file
1
2
3
4
5
6
7
8
9
10
11
12
13
class inventory:public mainCharacter
{
public:
	inventory();

	void addItem(string itemName);
	vector<string> getInventoryVector();
	void setInventoryVector();

	void update ( int frameNum );
protected:
	vector <string> inventoryVector; // creates a inventoryVector so that you can see what you have in inventory
};

This is inside the mainCharacter.cpp file
1
2
3
4
5
6
7
8
9
10
11
12
13
void inventory::addItem(string itemName)
{
	inventoryVector.push_back(itemName);
}

vector<string> inventory::getInventoryVector()
{
	return inventoryVector;
}

void inventory::setInventoryVector()
{
}


I have an inventory and want to be able to print it out in the main, but I'm having trouble doing so, and get errors whenever I try.
Here is the code for the main function right now.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int main()
{
	inventory playerInventory;
	string userInput = "loop";
	while(userInput != "Sword" && userInput != "Axe" && userInput != "Bow")
	{
		cout << "Weapon choices:\n(1)Sword\n(2)Axe\n(3)Bow and Arrow\n\n";
		cout << "Please choose which weapon that you would like to use: ";
		cin >> userInput;
		cout << endl;
	}


	if(userInput=="Sword")
	{
		playerInventory.addItem("Sword");
	}

	if(userInput=="Axe")
	{
		playerInventory.addItem("Axe");
	}

	if(userInput=="Bow")
	{
		playerInventory.addItem("Bow and Arrow");
	}
	
	cout << "\n\n";
	system("pause");
	return 0;
}


The reason I have "Bow" in the while loop is because it was giving me and infinite loop if I had "Bow and Arrow", and I realized it was setting userInput to "Bow". I have no idea why this is, so if someone can help me understand why that was as well that would be great.

Right now theoretically it should just add the information to the vector. I'm trying to figure out how to actually print out what is in the vector inside the main function. I'm assuming I have to put something inside the setInventoryVector, but i'm not exactly sure what I will need to put into it. Also would this be where I need to use polymorphism? If so, how would I accomplish this? Thanks in advance for any help that I can get.

EDIT: Fixed to have line numbers
Last edited on
There is a conceptual error here, methinks.

An "inventory" is not a type of person ("main character"). Hence it should not derive from a mainCharacter. A person has an inventory of possessions, so your main character class should look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Player
  {
  public:
    PlayerInventory inventory;
    ...
  };

class NPC: public Player
  {
  ...
  };

class MainCharacter: public Player
  {
  ...
  };

The polymorphism and inheritance should be used to express the items that the players (both NPC and MainCharacter) can use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
struct Item
  {
  virtual std::string name()           const { return "Nothing"; }
  virtual int         uses_remaining() const { return 0; }
  virtual int         damage()         const { return 0; }
  ...
  };

struct Axe: public Item
  {
  virtual std::string name()           const { return "Axe"; }
  virtual int         uses_remaining() const { return 1; }
  virtual int         damage()         const { return 10; }
  ...
  };

struct Bow: public Item
  {
  virtual std::string name()           const { return "Bow and Arrow"; }
  virtual int         uses_remaining() const { return arrows_left; }
  virtual int         damage()         const { return 5; }
  ...
  Bow(): arrows_left( 20 ) { }
  ...
  void add_arrows( int n ) { arrows_left += n; }
  ...
  private:
    int arrows_left;
  };

struct Halberd: public Axe
  {
  virtual std::string name()           const { return "Halberd"; }
  virtual int         damage()         const { return 20; }
  ...
  };

struct Sword: public Item
  {
  virtual std::string name()           const { return "Sword"; }
  virtual int         uses_remaining() const { return 1; }
  virtual int         damage()         const { return 15; }
  ...
  };

typedef std::vector <Item*> PlayerInventory;

To populate your inventory, just add items:
1
2
3
4
5
6
7
MainCharacter player1;

player1.inventory.push_back( new Sword );
player1.inventory.push_back( new Bow );

if (player1.inventory[ 1 ]->name() == "Bow and Arrow")
  player1.inventory[ 1 ]->add_arrows( 5 );

Hope this helps.
Last edited on
Well the way that I have it set up is so that you have the mainCharacter as a superclass and then there is 2 subclasses, one being for inventory, and the other being combat. Then I had another superclass being for the enemy having similar subclasses. And we needed user input, so I figured just ask for the starting weapon. I think the way that we are expected to do the values inside the vector is outside of the main function and then just call it inside the main function so that the main function is as few lines of code as possible.

So this is how I was going about it.

My assignment details are as follows:
Write an “RPG” style fighting game that uses Polymorphism and contains at least 2 multiple-tiered class hierarchies:

1. Create and use at least 2 class hierarchies. Some possible examples:
a. Units
b. Equipment
c. Combat
d. Magic
2. Game must have a loop and user input. The game can be turn-based or real-time, or both.
3. Polymorphism must be used for at least one of your class hierarchies.
4. Generate a “log” file which reports the progress of the game and any individual combat.


Yes, I understand how you have it set up. Your professor will think you've missed something in the lectures if you make an "inventory" a type of "main character".

Notice that the examples he gave you are all unique hierarchies of things: units (which can mean just about anything), equipment (aka inventory), combat, magical powers, etc.

For example, you can make combat work differently depending on the class and skill-level of the player character. This is a polymorphic design issue.

Notice how your equipment inventory is a polymorphic design issue, like I exampled for you above.


The purpose of polymorphism is to derive more specific things from less specific things.

A Fruit can be an Apple, a Pear, an Orange, etc. Pictorally, you have:

  Fruit
    --> Apple
    --> Pear
    --> Orange

An Apple can be a GrannySmith, a Roma, etc.
That is to say, an Apple is a specific type of Fruit. A GrannySmith is a specific type of Apple.

  Fruit --> Apple --> GrannySmith

An axe is not a type of person. Hence the following doesn't work:

  MainCharacter --> Axe

In your design you are separating like things and joining unlike things. Don't do that. Make your MainPlayer a type of PlayerCharacter. Make your EnemyPlayer a type of PlayerCharacter.

  PlayerCharacter
    --> MainCharacter
    --> EnemyCharacter

Your PlayerCharacter has an inventory, but he isn't a general type of inventory.


The purpose of polymorphism is to derive more specific things from less specific things.
If you get this concept your professor will be happy.

Hope this helps.
+50 Duoas


Inheritance forms an "is a" relationship. The child "is a" parent. If your classes don't make sense when phrased this way, then your inheritance setup is probably wrong.

Per Duoas' example... an Axe "is an" Item. This makes sense.

However in your example... you're saying an Inventory "is a" Main Character. This doesn't make sense.
Is this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Player
  {
  public:
    PlayerInventory inventory;
    ...
  };

class NPC: public Player
  {
  ...
  };

class MainCharacter: public Player
  {
  ...
  };
(Duoas's example)

an example of a 2 class heirarchy? cuz i don't exactly understand what identifies a class heirarchy, cuz the way I did it was the way that I understood it, but I see that's wrong, and I'm trying to learn, so all the help is much appreciated.

EDIT:
But yes this is making sense, I just have trouble of knowing what to put in the coding to make it work, since I am still new to all of this. Also would the inventory for each one go inside the class? the inventory being a vector from what I understand of this. Cuz I want to make both the enemy and the player have separate inventories, so that the mainCharacter can pick up what the enemy dropped after the mainCharacter defeated the enemy.

So say I want to create a weapon specifically for the mainCharacter. How would I go about doing that, and how would I call the list of Items so that I can put it into the mainCharacters inventory or the enemies inventory so that I can print out the mainCharacters inventory?
Last edited on
You have exactly the right kind of idea.

The idea behind polymorphism is "encapsulation". What that means is that like items can be used without knowing all the details of what that thing is.

If I say "speak" it will mean different things depending on whom I ask to speak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <vector>
using namespace std;

struct Animal
  {
  virtual const char* speak() const = 0;
  };

struct Dog: public Animal
  {
  const char* speak() const { return "Woof!"; }
  };

struct Cat: public Animal
  {
  const char* speak() const { return "Meow!"; }
  };

struct Human: public Animal
  {
  const char* speak() const { return "Hello!"; }
  };

int main()
  {
  // Create our zoo
  vector <Animal*> animals;
  animals.push_back( new Dog );
  animals.push_back( new Cat );
  animals.push_back( new Human );

  // Make each animal speak in its own way
  for (unsigned n = 0; n < animals.size(); n++)
    cout << animals[ n ]->speak() << endl;

  // Cleanup
  for (unsigned n = 0; n < animals.size(); n++)
    delete animals[ n ];

  return 0;
  }

In your example, an inventory is an inventory. It does not matter what has an inventory. As long as it has an inventory, it can use any object the other can.

Hence, if you do as per my example, both your main character and your enemy character can wield an Axe. If your enemy "drops it", you can "pick it up":

1
2
3
4
5
6
7
8
// This is the item the enemy will drop
Item* dropped_item = enemy.inventory[ index_of_the_axe ];

// Oh no! He drops his weapon!
enemy.inventory.erase( enemy.inventory.begin() + index_of_the_axe );

// Yay! The hero picks it up!
hero.inventory.push_back( dropped_item );

Hope this helps.
alright, that makes sense. Thank you so much, if I have more questions I'll definitely ask. Thanks again, this is a lot easier to understand than what my professor taught me. Thanks again, much appreciated.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <string>
#include "Player.cpp"
using namespace std;

int main()
{
	bool shouldExit = false;
	string playAgain;

	while (shouldExit == false)
	{
		//mainCharacter player;
		string userInput = "loop"; // set userInput to loop so that it goes into the while loop
		// while loop checks both upper case and lower case forms of the userInput and loops if they put something invalid in 
		while(userInput != "Sword" && userInput != "sword" && userInput != "axe" && userInput != "Axe" && userInput != "bow" && userInput != "Bow")
		{
			cout << "Weapon choices:\n(1)Sword\n(2)Axe\n(3)Bow and Arrow\n\n";
			cout << "Please choose which weapon that you would like to use: ";
			cin >> userInput;
			cout << endl;
		}

		// tells the player what their weapon of choice is
		if (userInput == "bow" || userInput == "Bow")
			cout << "Your weapon of choice: Bow and Arrow" << endl;
		else
			cout << "Your weapon of choice: " << userInput << endl;

		// adds the weapon they chose to the vector
		if(userInput=="Sword")
		{
			playerInventory.push_back( new "Sword");
		}

		if(userInput=="Axe")
		{
			playerInventory.push_back(new "Axe");
		}

		if(userInput=="Bow")
		{
			playerInventory.push_back(new "Bow and Arrow");
		}

		// used because it goes into an infinite loop otherwise
		while (playAgain != "No" && playAgain != "no")
		{
			playAgain = "no";
		}
		
		if(playAgain == "no")
		{
			shouldExit = true;
		}

	}
	
	cout << "\n\n";
	system("pause");
	return 0;
}


so this is what I have for my main function (using the same Item as in Duoas's example.)
I get a syntax error saying:
error C2143: syntax error : missing ';' before '.' c:\users\elias\desktop\c++ assignments\finalassignment\finalassignment\main.cpp 31


So I understand that it's saying i'm missing a semi colon. The same error occurs on lines 36 and 41.

When I comment out the if statements and the push_back statements it works fine, but as soon as i uncomment it those errors occur.

Also if I get rid of the playAgain, it causes the userInput while loop to be an infinite loop, which is wasn't before and all I added to it was just a few cases for if the user tried to put in lower case of each one and the added line of telling the user what weapon they chose.

Also, I realize that I need to create a specific inventory for each the player and the enemy. So would I do something like this...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Player
  {
  public:
    PlayerInventory inventory;
    ...
  };

class NPC: public Player
  {
      vector <string> enemyInventory;
  };

class MainCharacter: public Player
  {
      vector <string> mainCharInventory;
  };


Would this bit of code go in a .h file, and what kind of information do I need to put into each the Player, MainCharacter and NPC class.

Any help on this stuff would be much appreciate, I am still new to programming and am trying to figure this stuff out. Thanks in advance.
Last edited on
'playerInventory' is not declared
'playerInventory' is not declared


I changed PlayerInventory to playerInventory. So that's not giving me the issue. The syntax error is occurring when lines 31-44 are not commented out. That's the only time that the error occurs
Last edited on
Ok let me rephrase it: 'playerInventory' is not declared as a variable.

EDIT: if your class is named so declare a variable with another name where you can call push_back(). Note that you cannot write something like 'new "Sword"'. if you want that object to be initialized with that string omit new
Last edited on
ok, but that doesn't help me in anyway with the syntax error that i'm getting. I don't understand why it's spitting at me for a syntax error, when I comment that section of the code out it works fine, but as soon as I uncomment it, it immediately gives me the errors, but I don't see where the cause of the problem is.
What's so hard to understand? for line 31-44 there must be a variable named playerInventory otherwise the compiler will complain til end of time
oh, oops... i thought that since there was the playerInventory vector outside the main, that it carried into the main, that's why I was confused, but it's not the case, lol. I'm just a beginner programmer.

EDIT:
Thank you for the help. I got the error fixed.

But one question I have is why will the program go into an infinite loop when i try and remove the playAgain? It doesn't make sense, I tried debugging, and it seemed to be working the way that I expected it to, without going into an infinite loop.
Last edited on
since line 54 is the only place where 'shouldExit' becomes true which depends on 'playAgain'. without 'playAgain' 'shouldExit' never becomes true hence infinte loop (see line 11)

ok I see that you never ask the user whether he wants to play again. so you don't need that while loop on line 11 at all.
I figured out the infinite loop. I had it in there, but when i tried to play it again it never reset what playAgain was so that it would keep going through the process. I declared playAgain outside of the game loop, and didn't actually give it any data so it kept the information as playAgain = yes. I have an error when trying to delete the information from the inventory. Specific error information is at the bottom. Here's updated code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <string>
#include "Item.cpp"
using namespace std;

int main()
{
	vector <Item*> playerInventory;
	bool shouldExit = false;
	string playAgain;

	while (shouldExit == false)
	{
		//mainCharacter player;
		string userInput = "loop"; // set userInput to loop so that it goes into the while loop
		// while loop checks both upper case and lower case forms of the userInput and loops if they put something invalid in 
		while(userInput != "Sword" && userInput != "sword" && userInput != "axe" && userInput != "Axe" && userInput != "bow" && userInput != "Bow")
		{
			cout << "Weapon choices:\n(1)Sword\n(2)Axe\n(3)Bow and Arrow\n\n";
			cout << "Please choose which weapon that you would like to use: ";
			cin >> userInput;
			cout << endl;
		}

		// adds the weapon they chose to the vector and tells them what has been added to the inventory
		if(userInput=="Sword" || userInput == "sword")
		{
			playerInventory.push_back( new Sword);
			cout << "The " << userInput << " has been added to your inventory."<< endl;
		}

		if(userInput=="Axe" || userInput == "axe")
		{
			playerInventory.push_back(new Axe);
			cout << "The " << userInput << " has been added to your inventory."<< endl;
		}

		if(userInput=="Bow" || userInput == "bow")
		{
			playerInventory.push_back(new Bow);
			cout << "The " << userInput << " has been added to your inventory."<< endl;
		}

		// tells the person what their inventory looks like
		cout << "Your starting inventory: ";
		for( unsigned i = 0; i < playerInventory.size(); ++i)
		{
			cout << playerInventory[i]->name();
		}
		cout << endl << endl;

		// pauses and clears the console
		system("pause");
		system("cls");

		while (playAgain != "No" && playAgain != "no" && playAgain != "Yes" && playAgain != "yes")
		{
			cout << "Would you like to play again? ";
			cin >> playAgain;
                        cout << endl;
		}
		
		if(playAgain == "yes" || playAgain == "Yes")
		{
			shouldExit = false;

                        //ERROR (1)
			for(unsigned i = 0; i < playerInventory.size(); ++i)
			{
				delete playerInventory[i];
			}
		}
		if(playAgain == "no"  || playAgain == "No" )
		{
			shouldExit = true;
		}
	}
	
	cout << "\n\n";
	system("pause");
	return 0;
}


ERROR:
(1) Unhandled exception at 0x00ea1fce in finalAssignment.exe: 0xC0000005: Access violation reading location 0xfeeefeee.
-- (Found in call stacks)> finalAssignment.exe!main() Line 50 + 0x33 bytes C++
I guess that happens during the 2. cycle (when play again). You have to clear the vector after you deleted its elements so write after line 71: playerInventory.clear();
yeah that works, I didn't know the .clear() command. Was just trying to base it off of what Duoas wrote in his animal example. Thanks for the help coder777 and Duoas
Last edited on
so apparently, playing sound is really easy...

http://www.flexbeta.net/forums/index.php?showtopic=5504
http://www.cplusplus.com/forum/general/8510/

these sources seemed to be all that I needed in order to throw some sound in. As long as the song file is a .wav you should be fine.

actual code for it is:
You need to use windows.h

PlaySound(TEXT("sm64_happy_message.wav"), NULL, SND_ALIAS | SND_APPLICATION);

the for the song file you have to pass in the path to where it is, if it's in the same folder as the code you can just put the name of the .wav file.

If people know another method to this let me know...
Also, is there anyway to have the music playing in the background instead of preventing the program from preventing the next line of code to be accessed? Cuz the PlaySound() function makes the program wait till the sound is done playing.
Topic archived. No new replies allowed.