• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
VladimirMarenus

Attempting a "Simple" Vector-Based Inventory Test

17 posts in this topic

I am having an issue getting a vector-based inventory system to work. I am able to list the items in the inventory, but not able to allow a user-selected item to be accessed. Here is the code:

[CODE]
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;
cin >> selection;
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;
[/CODE]

^^^^ Everything above this line, works. I assume that my problem is the if statement, but I cannot figure out where I am going wrong in my syntax, or if there is a better way to do what I am doing.

[CODE]
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;
}
[/CODE]

I need for the player's choice to affect the message displayed. Here's a sample output of the 1st snippet:

[CODE]
Item 1: Healing Potion
Item 2: Healing Potion
Item 3: Healing Potion
Item 4: Potion of Fiery Balls
MAKE YOUR CHOICE.
Choice:
[/CODE]

From there, the player can type 1-4, and what I would like is for the number (minus 1, to reflect the vector starting at zero) to be passed to the find, which would then determine (in this small example) if the item at inventory[choice - 1] is a healing potion. If so, display "You used a healing potion!" and if it is not, to display "Fiery balls of joy". Obviously, to turn this into a "real" inventory system, it'll need much more tweaking- this excercise is to help me learn how to search vectors... next will be removing the item once it is used (really looking forward to that, too... )

Any advice you can offer would be awesome. Thanks for slogging through all this! Edited by VladimirMarenus
0

Share this post


Link to post
Share on other sites
`selection' is set to 0 at the beginning of the code, and then you have a `switch(selection)'. That doesn't seem right... `selection' can only possibly 0 at that point.
0

Share this post


Link to post
Share on other sites
[quote name='Álvaro' timestamp='1352813298' post='5000561']
`selection' is set to 0 at the beginning of the code, and then you have a `switch(selection)'. That doesn't seem right... `selection' can only possibly 0 at that point.
[/quote]

Sorry, missed a line! see edit- "cin >> selection;"
0

Share this post


Link to post
Share on other sites
Right nevermind I have my python hat on today and not my C++ hat [img]http://public.gamedev.net//public/style_emoticons/default/sad.png[/img]

The problem you are having is that the iterator returned by inventory.at(choice) not necessarily needs to be inventory.end(), if you change the end into an inventory.at(choice) it should work. Be careful though as choice can index outside of your inventory vector as maximum choice is defined as inventory.size() + 1, see the output loop above in which you create the choice menu.

Also more info on find [url="http://www.cplusplus.com/reference/algorithm/find/"]here[/url] Edited by NightCreature83
0

Share this post


Link to post
Share on other sites
I don't really understand why you are trying to use "find" in there, the best approach would be adding a itemType on the "aItem" struct/class and look directly at the choice - 1 (don't forget to check if choice is > 1 and <= inventory.size()) to check if itemType == SOME_POTION_IDENTIFIER.

If you really want to use the find, the first thing that I see that I believe is wrong is that the search range of find doesn't include de second argument, and this second argument is returned in case of a search failure. So you should replace the != inventory.end() by inventory.at(choice).
Also, I do not think find will be able to compare the value the way you are passing to it.
How is the aItem struct/class implemented?

Edited by KnolanCross
0

Share this post


Link to post
Share on other sites
[quote name='KnolanCross' timestamp='1352821074' post='5000600']
How is the aItem struct/class implemented?
[/quote]

The implementation is mostly to teach myself vectors. At the end of it all, I want a simple program that will add an item to a vector, show a list of items, allow the player to pick one, execute the correct code for the item selected (not simply by looking at the choice, as these items are consumable- choice 3 won't always be a healing potion, for example), and then delete the item after it is used. I am attempting a larger project, but didn’t want my difficulties with this bit of code muddling up with difficulties from the rest of the code! So I have this running as a self-contained solution. Once I’m comfortable with managing vectors, I’ll design a couple more “simulations”, and then hold my breath and pray as I turn it into actual game code and merge it with my tiny project!

I realize that I'm probably making a mountain range out of a molehill... but I'm trying to learn as I go!
0

Share this post


Link to post
Share on other sites
Well, as I said, comparing by name is a bad idea, it is slow and prone to error. If you using char* of char[], they won't compare as you may want. For instance:
[source lang="cpp"] char* a = "hello world";
char b[] = "hello world";

if (a == b){
printf("Ok");
}
else{
printf("Nope.");
}[/source]
Will print "Nope.", which is not intuitive at all (it has to do with memory areas used by a and b).

Using find is also not needed as you know which item you need to check, even if you get it working (I believe that if you use Strings, aItem is a struct and they are the first element declared in the struct it will work as intended), you will be tossing away processing (as you need to find the element in the array).

I keep my opinion of adding an itemType, each type is an ID that represents the item type (armor, potion, quest item and so on). So you just check if the item at that point have the potion id. The main advantage of a vector over a list is that you can directly accesss an item... take advantage of it =D Edited by KnolanCross
1

Share this post


Link to post
Share on other sites
[quote name='KnolanCross' timestamp='1352828361' post='5000622']
...The main advantage of a vector over a list is that you can directly accesss an item... take advantage of it =D
[/quote]

Oh, my God. That made it so much easier. I ended up with:

[CODE]
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;
cin >> selection;
int a = 1;
switch (selection)
{

case 1:
cout << "Which item would you like to use?" << endl;

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;
//This checks for an invalid response. Add in non-int
if ((choice - 1) >= inventory.size())
{
cout << "Choice out of bounds. Stop being a dick." << endl;
}
else
{

if(inventory[choice - 1].itemType == 01)
{
cout << "You used a healing potion!" << endl;
}

else if(inventory[choice-1].itemType == 02)
{
cout << "FIERY BALLS OF JOY!" << endl;
}

else
{
cout << "Invalid Item type" << endl;
}
}
break;
case 2:
cout << "Why do you have to be so difficult? Pick 1!" << endl;
break;
[/CODE]

This code compiles and runs- but is it good code, in your opinion?

My next task is to figure out how to delete the item from the vector and move everything up to fill the spot. -_- That'll come later, I am still basking in the delight of this working. Thanks!
0

Share this post


Link to post
Share on other sites
The code is artificial, and more importantly, it doesn't do anything (except printing stuff). Thus there's very little that could be wrong with it on low level, and in the absence of context it's hard to say anything about design issues.

Just some cosmetic things I'd point out to a student:
- "a" is useless because you could be printing "index+1" instead
- any variables like "choice" should be defined as close as possible to where you actually use them for the first time
- instead of writing "choice-1" everywhere, sanitize the number once to the value you actually want (-=1)
- finally, magic numbers like "01" and "02" are generally bad; in a real program you would likely use an enum and descriptive labels like ITEM_HEALTHPOT or ITEM_FIREPOT

Which compiler are you using? If it's new enough to have some C++11 features, they can make your life easier in small (and occasionally big) ways.
0

Share this post


Link to post
Share on other sites
[quote name='KnolanCross' timestamp='1352828361' post='5000622']
Using find is also not needed as you know which item you need to check, even if you get it working (I believe that if you use Strings, aItem is a struct and they are the first element declared in the struct it will work as intended), you will be tossing away processing (as you need to find the element in the array).
[/quote]
Actually his implementation will always work regardless of where the string is stored in the same struct as he is providing an == operator which find will call for the data type you give it.

Also another tip: instead of doing index++, try to use ++index. In this case it doesn't matter but it is a good habit to have, so when you only want to increment and decrement a variable by 1 ever and nothing else write ++var or --var. The reason behind this is that the ++operator or --operator(both pre and post increment or decrement) can be overloaded and do a lot of work that is unnecessary in that particular case. Edited by NightCreature83
0

Share this post


Link to post
Share on other sites
[quote name='Stroppy Katamari' timestamp='1352854817' post='5000730']
The code is artificial, and more importantly, it doesn't do anything (except printing stuff). Thus there's very little that could be wrong with it on low level, and in the absence of context it's hard to say anything about design issues.

Just some cosmetic things I'd point out to a student:
- "a" is useless because you could be printing "index+1" instead
- any variables like "choice" should be defined as close as possible to where you actually use them for the first time
- instead of writing "choice-1" everywhere, sanitize the number once to the value you actually want (-=1)
- finally, magic numbers like "01" and "02" are generally bad; in a real program you would likely use an enum and descriptive labels like ITEM_HEALTHPOT or ITEM_FIREPOT

Which compiler are you using? If it's new enough to have some C++11 features, they can make your life easier in small (and occasionally big) ways.
[/quote]

Thank you very much. I realize the artificial nature. This is a glorified snippet that is mostly designed to teach me how to use and modify vectors. The suggestions I was looking for are exactly the ones you mentioned- just good housekeeping and dev habits in general. I'm learning this myself, so I'm not able to get the benefit of a teacher standing over me going "No- that won't work in six months when you're doing something better."

I'm using Microsoft VS 2012- I'm not sure what "C++11 features" are, but if they make my life easier, I'd certainly be interested in hearing about them!

EDIT: I've applied the changes you suggested, and the code reads much better.

EDIT 2: The next step for me is to turn this into a class, I suppose! Edited by VladimirMarenus
0

Share this post


Link to post
Share on other sites
What do you mean by turning it into a class?

Also, please don't place extended logic inside switch statements. It's a nightmare to read. Check this out:

[source lang="cpp"]
void processItemSelect() {
int choice = -1;

while(choice == -1) {
cout << "Which item would you like to use?" << endl;
for(vector<aItem>::size_type index = 0; index < inventory.size(); ++index) {
cout << "Item " << index + 1 << ": " << inventory[index].itemName << endl;
}
cout << "MAKE YOUR CHOICE." << endl << "Choice: ";
cin >> choice;
--choice;
if((choice >= inventory.size()) || (choice < 0)) {
choice = -1;
cout << "Choice out of bounds. Stop being a dick." << endl << endl;
}
}
switch(inventory[choice].itemType) {
case ITEM_POTION:
cout << "You used a healing potion!" << endl;
break;
case ITEM_BALLS:
cout << "FIERY BALLS OF JOY!" << endl;
break;
default:
cout << "Invalid Item type" << endl;
break;
}
}

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

switch (selection) {
case 1:
processItemSelect();
break;
case 2:
cout << "Why do you have to be so difficult? Pick 1!" << endl;
break;
}

return 0;
}[/source]

Finally, do not prefix numeric literals with a zero. That's the notation for the octal numbering system:

10 is 10.
010 is 8. Edited by Khatharr
0

Share this post


Link to post
Share on other sites
[quote name='VladimirMarenus' timestamp='1352885306' post='5000840']
I'm using Microsoft VS 2012- I'm not sure what "C++11 features" are, but if they make my life easier, I'd certainly be interested in hearing about them!
[/quote]C++11 is the newest C++ standard. VS2012 supports about half of the new features. Most of the features are not relevant to a beginner, but some of them are seriously worth learning immediately. Together, they almost feel like you are writing in a different language.

The auto keyword (lets you type "auto" in many situations where you'd otherwise have to type something painful like "std::vector<std::pair<int, myType>>::iterator_type")
[url="http://en.wikipedia.org/wiki/C%2B%2B11#Type_inference"]http://en.wikipedia....#Type_inference[/url]
Range-based for loop (use whenever you can):
[url="http://en.wikipedia.org/wiki/C%2B%2B11#Range-based_for-loop"]http://en.wikipedia....-based_for-loop[/url]
nullptr (use whenever you can):
[url="http://en.wikipedia.org/wiki/C%2B%2B11#Null_pointer_constant"]http://en.wikipedia....ointer_constant[/url]

Lambdas are a bit more obscure than the above, but not actually hard. If you have the capacity, check them out. Standard containers like vector, standard algorithms and lambdas together are magic.
[url="http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions"]http://en.wikipedia....and_expressions[/url]

Smart pointers, unique_ptr and smart_ptr: you *have to* eventually learn these or you won't be coding good C++11. However, you don't need to touch them at all until you start using "new" and start seeing naked pointers like int* or SomeType* in your code. Naked pointers are evil. Smart pointers get rid of them.
[url="http://en.wikipedia.org/wiki/Smart_pointer"]http://en.wikipedia....i/Smart_pointer[/url]

The biggest thing that you unfortunately don't have yet in VS2012 is uniform initialization.
0

Share this post


Link to post
Share on other sites
[quote name='Khatharr' timestamp='1352888631' post='5000848']
What do you mean by turning it into a class?
[/quote]

Well, this standalone exercise was standalone because I realized that I had no idea how to create an inventory system- this is all written from scratch (I'm still enough of a beginner to feel like a "Master Programmer" for getting it to work [img]http://public.gamedev.net//public/style_emoticons/default/rolleyes.gif[/img] ). I actually have a very basic text RPG with some functional abilities, and wanted to isolate this painful learning experience from the working code! The end result of this is to create a class with functions that I can call from within the game code, in order to perform inventory functions without cluttering up the main .cpp.
0

Share this post


Link to post
Share on other sites
Gaah, 2 posts while I was editing. Derp.

Ah, I see. You just mean implementing it. I'm glad to hear the you're enjoying your successes. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

Edit - Occurred to mention it while I was outside - You would probably be better off placing the usage message in the item's effect processing. That way you just have to proc the item effect of the selected item instead of switching to print the usage message. Edited by Khatharr
0

Share this post


Link to post
Share on other sites
[quote name='Khatharr' timestamp='1352890119' post='5000857']
Gaah, 2 posts while I was editing. Derp.

Ah, I see. You just mean implementing it. I'm glad to hear the you're enjoying your successes. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

Edit - Occurred to mention it while I was outside - You would probably be better off placing the usage message in the item's effect processing. That way you just have to proc the item effect of the selected item instead of switching to print the usage message.
[/quote]

Thank you! :)

I see... and thank you for your code example- that looks much more friendly than what I'm hacking together! Got a lot to learn, but getting there...
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0